SpringBoot整合JWT实现安全认证

Spring Boot 整合 JWT 实现一个安全的Restful 接口?

JWT 是一种用于身份验证和授权的开放标准(RFC 7519),它允许使用签名验证和信息加密来传输数据。集成 JSON Web Token(JWT)到 Spring Boot 以实现安全的 RESTful 接口是一种常见的做法。下面是一个简单的步骤,展示如何在 Spring Boot 中整合 JWT。

第一步、添加POM依赖

首先,需要添加JWT相关依赖到POM文件中。这里需要根据自己项目的版本对JWT版本做对应的适配,否则可能会出现版本差异导致相关功能不能用的情况出现。

复制代码
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

创建JWT工具类

需要创建一个JWT的通用工具类,完成JWT的创建与解析操作,同时需要完成认证的签发、验证令牌等操作。如下所示。

复制代码
@Component
public class JwtUtils {

    private static final String SECRET_KEY = "yourSecretKey";
    private static final long EXPIRATION_TIME = 86400000; // 24 hours

    public String generateToken(String username) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + EXPIRATION_TIME);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }

    public String getUsernameFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();

        return claims.getSubject();
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }
}

注意这里需要指定对应的秘钥以及过期时间等信息。

创建接口安全配置类

引入SpringSecurity的POM依赖

复制代码
<!-- spring security 安全认证 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

创建配置类

创建一个 Spring Security 配置类,配置认证和授权规则,并且集成 JWT。

复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // 配置用户认证信息
        auth.inMemoryAuthentication()
                .withUser("admin").password(passwordEncoder().encode("password")).roles("ADMIN")
                .and()
                .withUser("user").password(passwordEncoder().encode("password")).roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/authenticate").permitAll()
            .antMatchers(HttpMethod.GET, "/api/**").hasAnyRole("USER", "ADMIN")
            .antMatchers(HttpMethod.POST, "/api/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

需要注意,这里提供了一个

UsernamePasswordAuthenticationFilter的拦截器,这个拦截器就是用来进行请求拦截进行判断处理的。

复制代码
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
    @Autowired
    private JwtUtils jwtUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                    HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException{
              // 具体使用 
              // 1、通过Request请求获取到请求头中的Token信息
              // 2、将Token信息传入到JwtUtils进行认证,如果通过则继续调用
              // 如果拦截返回未授权信息
        chain.doFilter(request, response);
    }
}

创建认证请求实体对象

创建一个通用的认证请求以及相应对象来进行测试调用。

复制代码
public class AuthRequest {

    private String username;
    private String password;

    // getters and setters
}

public class AuthResponse {

    private final String token;

    public AuthResponse(String token) {
        this.token = token;
    }

    // getter
}

创建 REST 控制器

创建 REST 控制器来处理认证请求,并且使用 JWT 工具类来生成令牌。

复制代码
@RestController
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @PostMapping("/authenticate")
    public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthRequest authenticationRequest) throws Exception {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword()));
        } catch (AuthenticationException e) {
            throw new Exception("Incorrect username or password", e);
        }

        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
        final String token = jwtUtils.generateToken(userDetails.getUsername());

        return ResponseEntity.ok(new AuthResponse(token));
    }
}

创建完成之后,就可以通过接口调用认证接口,然后获取到认证的Token令牌,然后根据访问令牌来进行身份验证,这样就可以保证接口调用的安全性。

相关推荐
开开心心就好3 分钟前
系统管理工具,多功能隐私清理文件粉碎工具
java·网络·windows·r语言·电脑·excel·symfony
随丶芯9 分钟前
IDEA安装leetcode-editor插件
java·开发语言
范什么特西14 分钟前
下载idea旧版本
java·ide·intellij-idea
计算机毕设指导620 分钟前
基于微信小程序的钓鱼论坛系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
qq_124987075321 分钟前
基于微信小程序的宠物交易平台的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·微信小程序·小程序·毕业设计·计算机毕业设计
小毅&Nora22 分钟前
【Java线程安全实战】⑧ 阶段同步的艺术:Phaser 与 Condition 的高阶玩法
java·多线程
内存不泄露23 分钟前
基于Spring Boot和Vue的企业办公自动化系统设计与实现
java·vue.js·spring boot·intellij-idea
禹曦a24 分钟前
Java实战:Spring Boot 构建电商订单管理系统RESTful API
java·开发语言·spring boot·后端·restful
code_lfh24 分钟前
Spring Boot测试类的使用参考
java·spring boot·junit
芒克芒克24 分钟前
虚拟机类加载机制
java·开发语言·jvm