SpringSecurity基于JWT实现无状态认证

举报
林欣 发表于 2024/08/31 16:23:51 2024/08/31
【摘要】 Spring Security 结合 JWT(JSON Web Tokens)实现无状态认证是现代Web应用中的一种常见做法,特别适用于需要RESTful API的微服务架构。JWT提供了一种在客户端和服务器之间安全传输信息的方式,无需在服务器端存储用户的会话信息,从而实现了无状态认证。 1. 理解JWTJWT是一种用于双方之间安全传输信息的简洁的、URL安全的令牌标准。一个JWT实际上是一...

Spring Security 结合 JWT(JSON Web Tokens)实现无状态认证是现代Web应用中的一种常见做法,特别适用于需要RESTful API的微服务架构。JWT提供了一种在客户端和服务器之间安全传输信息的方式,无需在服务器端存储用户的会话信息,从而实现了无状态认证。

1. 理解JWT

JWT是一种用于双方之间安全传输信息的简洁的、URL安全的令牌标准。一个JWT实际上是一个紧凑的、URL安全的JSON对象,它传递了信息的一种方式。JWT由三部分组成,它们通过点(.)分隔,分别是:

  • Header(头部):声明了令牌的类型(通常是JWT)以及所使用的签名算法(如HMAC SHA256或RSA)。
  • Payload(负载):包含了声明(claims)。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型:注册声明、公共声明和私有声明。
  • Signature(签名):是对前两部分的签名,以防止数据被篡改。

2. 引入依赖

首先,在你的Spring Boot项目中引入Spring Security和JWT相关的依赖。如果你使用Maven,可以添加如下依赖:

<!-- Spring Boot Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- JWT -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

3. 配置JWT过滤器

你需要创建一个JWT过滤器,用于解析JWT,并基于JWT中的信息设置Spring Security的SecurityContext。

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(jwt);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (jwtUtil.validateToken(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

                usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }

        chain.doFilter(request, response);
    }
}

4. 配置Spring Security

在你的Spring Security配置中,你需要配置HTTP安全,添加JWT过滤器,并配置无状态会话。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .exceptionHandling().and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    // 其他配置...
}

5. 创建JWT工具类

你需要一个JWT工具类来生成和验证JWT。

@Component
public class JwtUtil {
    // JWT密钥
    private String secret = "your_secret_key";

    // 生成JWT
    public String generateToken(String username) {
        // 逻辑...
    }

    // 验证JWT
    public boolean validateToken(String token, UserDetails userDetails) {
        // 逻辑...
    }

    // 提取JWT中的用户名
    public String extractUsername(String token) {
        // 逻辑...
    }
}

6. 认证和授权

在你的登录接口中,当用户成功认证后,生成一个JWT并返回给客户端。客户端在后续的请求中携带这个JWT,Spring Security通过JWT过滤器解析JWT,并进行相应的授权检查。

以上是使用Spring Security和JWT实现无状态认证的基本步骤。根据你的具体需求,可能还需要进行一些调整和扩展。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。