赞
踩
在Spring Boot应用中整合Spring Security和JSON Web Tokens (JWT) 以实现无状态的身份验证,通常涉及以下步骤:
添加依赖:
在您的pom.xml
(Maven)或build.gradle
(Gradle)文件中添加Spring Security和JWT所需的依赖。例如,使用jjwt
库来生成和解析JWT令牌:
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>最新版本号</version>
</dependency>
Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt:最新版本号'
配置Spring Security:
创建一个配置类,继承WebSecurityConfigurerAdapter
并覆盖configure(HttpSecurity http)
方法来配置安全规则,例如,启用JWT验证:
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Value("${app.jwt.secret}") private String jwtSecret; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(HttpMethod.POST, "/login").permitAll() .anyRequest().authenticated() .and() .exceptionHandling().authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED)) .and() .addFilterBefore(new JWTAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // JWT 相关类,如 JWTAuthenticationFilter 和 JWTAuthorizationFilter // ... }
创建JWT过滤器:
创建JWT过滤器,如JWTAuthenticationFilter
用于处理登录请求并生成JWT,JWTAuthorizationFilter
用于验证请求头中的JWT并建立认证。
public class JWTAuthenticationFilter extends OncePerRequestFilter { private final AuthenticationManager authenticationManager; public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // 从登录请求中提取用户名和密码,执行身份验证 // ... // 成功后,生成JWT并返回给客户端 String token = Jwts.builder() .setSubject(principal.getUsername()) .setExpiration(Date.from(Instant.now().plus(Duration.ofMinutes(30))) // 设置有效期 .signWith(SignatureAlgorithm.HS512, jwtSecret.getBytes()) // 使用密钥签名 .compact(); // 返回JWT至客户端 } } public class JWTAuthorizationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // 从请求头中提取JWT String token = getTokenFromRequest(request); if (token != null && JWTUtil.validateToken(token, jwtSecret)) { // 自定义JWTUtil类验证JWT有效性 // 解析JWT获取用户名并建立身份认证 // ... } else { // 无效或缺失的JWT,可选择跳转至登录页或返回错误信息 } chain.doFilter(request, response); } private String getTokenFromRequest(HttpServletRequest request) { // 从请求头 Authorization 中提取Bearer类型的JWT // ... } }
实现UserDetailsService接口:
实现UserDetailsService
接口以从数据库或其他存储中加载用户详细信息。
配置JWT密钥和过期时间:
在application.properties
或application.yml
中配置JWT密钥和过期时间。
app.jwt.secret=your_jwt_secret_key_here
通过上述步骤,您将在Spring Boot应用中整合了Spring Security和JWT,实现无状态的身份验证机制。请注意,以上代码片段仅供参考,实际开发中请根据您的需求和环境进行适当调整。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。