返回

Spring Security 无缝整合 JWT 掌控安全,你怕了吗?

后端

如何将 JWT 无缝集成到 Spring Security 中

简介

在现代应用程序开发中,JSON Web Token(JWT) 已成为实现身份验证和授权的安全且灵活的解决方案。将其与 Spring Security 框架集成可为您的应用程序提供强大的身份管理功能。本文将引导您完成将 JWT 与 Spring Security 无缝集成的步骤,涵盖从依赖项配置到自定义身份验证过滤器的所有内容。

为什么使用 JWT?

使用 JWT 具有以下优势:

  • 单点登录(SSO): 允许用户使用单个令牌访问多个系统。
  • 安全性: 通过数字签名确保令牌的完整性和真实性。
  • 灵活性: 可以根据需要定制令牌内容。

Spring Security 中的 JWT

在 Spring Security 中,JWT 可用于身份验证和授权:

  • 身份验证: 用户发送 JWT 令牌,服务器验证其有效性,并允许访问系统。
  • 授权: 服务器检查用户角色和权限,决定用户可以访问哪些资源。

集成步骤

1. 添加依赖项

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. 创建 JWT 工具类

import io.jsonwebtoken.*;
import java.util.Date;

public class JwtUtil {

    private String secretKey;

    public JwtUtil(String secretKey) {
        this.secretKey = secretKey;
    }

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

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

    public String parseToken(String token) {
        Jws<Claims> claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token);

        return claims.getBody().getSubject();
    }
}

3. 配置 Spring Security

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(new JwtAuthenticationFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class)
                .csrf().disable();
    }
}

4. 创建 JWT 登录授权过滤器

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private JwtUtil jwtUtil;

    public JwtAuthenticationFilter(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            String username = jwtUtil.parseToken(token.substring(7));
            UserDetails userDetails = new UserDetailsImpl(username);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

        filterChain.doFilter(request, response);
    }
}

结论

通过遵循这些步骤,您已成功将 JWT 与 Spring Security 集成。现在,您的应用程序可以安全地使用 JWT 进行身份验证和授权,享受单点登录、增强安全性以及灵活性的好处。

常见问题解答

1. JWT 和 Spring Security 之间有什么区别?

  • JWT 是一个安全令牌,用于在系统之间安全地传输信息,而 Spring Security 是一个框架,用于保护 Spring 应用程序。

2. 如何在应用程序中使用 JWT?

  • 服务器生成 JWT,客户端存储并发送 JWT 以进行身份验证,服务器验证 JWT 并授予访问权限。

3. 如何确保 JWT 的安全性?

  • 使用数字签名算法和一个安全的密钥来防止伪造和篡改。

4. JWT 与会话 cookie 有什么区别?

  • JWT 存储在客户端,而会话 cookie 存储在服务器端,并且在会话过期时失效。

5. 我可以在 JWT 中存储什么信息?

  • 您可以存储有关用户、角色、权限和任何其他相关信息的自定义声明。