当前位置:   article > 正文

SpringSecurity集成JWT_springsecurity 和jwt

springsecurity 和jwt

使用 Spring Security 集成 JWT(JSON Web Token)身份验证是一种常见的方式来实现基于令牌的身份验证。在 Spring Boot 应用程序中使用 Spring Security 和 JWT,可以创建一个安全、可扩展的身份验证系统。下面是一个示例,展示如何在 Spring Boot 项目中集成 JWT 身份验证:

1. 添加依赖

首先,在你的 pom.xml 中添加与 JWT 和 Spring Security 相关的依赖:

  1. <dependencies>
  2. <!-- Spring Boot Starter Security -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-security</artifactId>
  6. </dependency>
  7. <!-- JJWT (Java JSON Web Token) -->
  8. <dependency>
  9. <groupId>io.jsonwebtoken</groupId>
  10. <artifactId>jjwt-api</artifactId>
  11. <version>0.11.5</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>io.jsonwebtoken</groupId>
  15. <artifactId>jjwt-impl</artifactId>
  16. <version>0.11.5</version>
  17. <scope>runtime</scope>
  18. </dependency>
  19. <dependency>
  20. <groupId>io.jsonwebtoken</groupId>
  21. <artifactId>jjwt-jackson</artifactId>
  22. <version>0.11.5</version>
  23. <scope>runtime</scope>
  24. </dependency>
  25. </dependencies>

2. 配置 JWT 密钥

application.propertiesapplication.yml 文件中配置用于签署和验证 JWT 的密钥:

properties code

  1. # JWT 配置
  2. jwt.secret=your-secret-key
  3. jwt.expiration-time=86400000 # 令牌有效时间,单位为毫秒
  4. jwt.header=Authorization # JWT 令牌的请求头
  5. jwt.prefix=Bearer # 令牌前缀

3. JWT 工具类

创建一个工具类来生成和解析 JWT:

  1. import io.jsonwebtoken.Claims;
  2. import io.jsonwebtoken.Jwts;
  3. import io.jsonwebtoken.SignatureAlgorithm;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.stereotype.Component;
  6. import java.util.Date;
  7. @Component
  8. public class JwtTokenUtil {
  9. @Value("${jwt.secret}")
  10. private String secret;
  11. @Value("${jwt.expiration-time}")
  12. private long expirationTime;
  13. // 生成 JWT 令牌
  14. public String generateToken(String username) {
  15. Date now = new Date();
  16. Date expiryDate = new Date(now.getTime() + expirationTime);
  17. return Jwts.builder()
  18. .setSubject(username)
  19. .setIssuedAt(now)
  20. .setExpiration(expiryDate)
  21. .signWith(SignatureAlgorithm.HS512, secret)
  22. .compact();
  23. }
  24. // 解析 JWT 令牌
  25. public String getUsernameFromToken(String token) {
  26. Claims claims = Jwts.parser()
  27. .setSigningKey(secret)
  28. .parseClaimsJws(token)
  29. .getBody();
  30. return claims.getSubject();
  31. }
  32. // 验证 JWT 令牌是否有效
  33. public boolean validateToken(String token, String username) {
  34. String tokenUsername = getUsernameFromToken(token);
  35. Date expiration = Jwts.parser()
  36. .setSigningKey(secret)
  37. .parseClaimsJws(token)
  38. .getBody()
  39. .getExpiration();
  40. return (username.equals(tokenUsername) && expiration.after(new Date()));
  41. }
  42. }

4. JWT 过滤器

创建一个过滤器,用于在请求中拦截 JWT 令牌,并根据令牌进行身份验证

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  3. import org.springframework.security.core.context.SecurityContextHolder;
  4. import org.springframework.security.core.userdetails.UserDetails;
  5. import org.springframework.security.core.userdetails.UserDetailsService;
  6. import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
  7. import org.springframework.stereotype.Component;
  8. import org.springframework.web.filter.OncePerRequestFilter;
  9. import javax.servlet.FilterChain;
  10. import javax.servlet.ServletException;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13. import java.io.IOException;
  14. @Component
  15. public class JwtAuthenticationFilter extends OncePerRequestFilter {
  16. @Autowired
  17. private JwtTokenUtil jwtTokenUtil;
  18. @Autowired
  19. private UserDetailsService userDetailsService;
  20. @Override
  21. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  22. throws ServletException, IOException {
  23. String header = request.getHeader("${jwt.header}");
  24. if (header != null && header.startsWith("${jwt.prefix} ")) {
  25. String token = header.replace("${jwt.prefix} ", "");
  26. String username = jwtTokenUtil.getUsernameFromToken(token);
  27. if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
  28. UserDetails userDetails = userDetailsService.loadUserByUsername(username);
  29. if (jwtTokenUtil.validateToken(token, username)) {
  30. UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
  31. userDetails, null, userDetails.getAuthorities());
  32. authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
  33. SecurityContextHolder.getContext().setAuthentication(authentication);
  34. }
  35. }
  36. }
  37. chain.doFilter(request, response);
  38. }
  39. }

5. 配置 Spring Security

SecurityConfig 中配置 Spring Security 来使用 JWT 过滤器:

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.security.authentication.AuthenticationManager;
  5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  8. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  9. import org.springframework.security.config.http.SessionCreationPolicy;
  10. import org.springframework.security.core.userdetails.UserDetailsService;
  11. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  12. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
  13. @Configuration
  14. @EnableWebSecurity
  15. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  16. @Autowired
  17. private JwtAuthenticationFilter jwtAuthenticationFilter;
  18. @Autowired
  19. private UserDetailsService userDetailsService;
  20. @Bean
  21. public BCryptPasswordEncoder passwordEncoder() {
  22. return new BCryptPasswordEncoder();
  23. }
  24. @Override
  25. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  26. auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  27. }
  28. @Override
  29. protected void configure(HttpSecurity http) throws Exception {
  30. http.cors().and().csrf().disable()
  31. .authorizeRequests()
  32. .antMatchers("/auth/**").permitAll() // 允许未认证访问登录和注册等路径
  33. .anyRequest().authenticated() // 其他请求需要身份验证
  34. .and()
  35. .exceptionHandling()
  36. .and()
  37. .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  38. // 添加 JWT 过滤器
  39. http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
  40. }
  41. @Override
  42. @Bean
  43. public AuthenticationManager authenticationManagerBean() throws Exception {
  44. return super.authenticationManagerBean();
  45. }
  46. }

6. 登录和令牌颁发

在控制器中实现登录和令牌颁发:

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.http.ResponseEntity;
  3. import org.springframework.security.authentication.AuthenticationManager;
  4. import org.springframework.security.authentication.BadCredentialsException;
  5. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  6. import org.springframework.security.core.userdetails.UserDetails;
  7. import org.springframework.security.core.userdetails.UserDetailsService;
  8. import org.springframework.web.bind.annotation.*;
  9. @RestController
  10. @RequestMapping("/auth")
  11. public class AuthController {
  12. @Autowired
  13. private AuthenticationManager authenticationManager;
  14. @Autowired
  15. private JwtTokenUtil jwtTokenUtil;
  16. @Autowired
  17. private UserDetailsService userDetailsService;
  18. @PostMapping("/login")
  19. public ResponseEntity<?> login(@RequestBody AuthRequest authRequest) {
  20. try {
  21. // 进行身份验证
  22. authenticationManager.authenticate(
  23. new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
  24. );
  25. // 加载用户详细信息
  26. UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
  27. // 生成 JWT 令牌
  28. String token = jwtTokenUtil.generateToken(userDetails.getUsername());
  29. // 返回令牌
  30. return ResponseEntity.ok(new AuthResponse(token));
  31. } catch (BadCredentialsException e) {
  32. return ResponseEntity.status(401).body("Invalid credentials");
  33. }
  34. }
  35. }

数据模型:

  • AuthRequest:表示登录请求,包括用户名和密码。
  • AuthResponse:表示登录响应,包括生成的 JWT 令牌。
  1. // 登录请求数据模型
  2. public class AuthRequest {
  3. private String username;
  4. private String password;
  5. // Getters and setters...
  6. }
  7. // 登录响应数据模型
  8. public class AuthResponse {
  9. private String token;
  10. public AuthResponse(String token) {
  11. this.token = token;
  12. }
  13. // Getters and setters...
  14. }

通过以上配置和代码,你可以在 Spring Boot 项目中集成 JWT 身份验证。你可以根据自己的需求进一步定制和优化。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/638515
推荐阅读
相关标签
  

闽ICP备14008679号