java Spring安全令牌刷新和JWT签名与本地计算的签名不匹配

zqry0prt  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(230)

我一直在努力与令牌刷新与Spring Boot 安全。
在此之前,我已经完成了与JWT的工作身份验证,但现在当我创建这个刷新系统时,它再也无法登录了。说“JWT签名与本地计算的签名不匹配。JWT有效性无法Assert,不应被信任。"。我试图通过在这里找到的不同主题和从Google找到的不同主题解决这个问题。
现在,我不能理解这种情况下,错误来自哪里.我崩溃的JWT验证方法:
JwtUtils.java

  1. package com.testapp.springbooot.security.jwt;
  2. import java.security.Key;
  3. import java.util.Date;
  4. import com.testapp.springbooot.security.services.UserDetailsImpl;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Value;
  8. import org.springframework.security.core.Authentication;
  9. import org.springframework.stereotype.Component;
  10. import io.jsonwebtoken.*;
  11. import io.jsonwebtoken.security.Keys;
  12. @Component
  13. public class JwtUtils {
  14. private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
  15. @Value("${testapp.app.jwtSecret}")
  16. private String jwtSecret;
  17. @Value("${testapp.app.jwtExpirationMs}")
  18. private int jwtExpirationMs;
  19. public String generateJwtToken(Authentication authentication) {
  20. UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
  21. return Jwts.builder()
  22. .setId("" + userPrincipal.getId())
  23. .setIssuedAt(new Date())
  24. .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
  25. .signWith(key(), SignatureAlgorithm.HS512)
  26. .compact();
  27. }
  28. private Key key() {
  29. return Keys.secretKeyFor(SignatureAlgorithm.HS512);
  30. }
  31. public String getUserNameFromJwtToken(String token) {
  32. return Jwts.parserBuilder().setSigningKey(key()).build()
  33. .parseClaimsJws(token).getBody().getSubject();
  34. }
  35. public String getEmailFromJwtToken(String token) {
  36. return Jwts.parserBuilder().setSigningKey(key()).build()
  37. .parseClaimsJws(token).getBody().getSubject();
  38. }
  39. public Date getExpirationFromJwtToken(String token) {
  40. return Jwts.parserBuilder().setSigningKey(key()).build()
  41. .parseClaimsJws(token).getBody().getExpiration();
  42. }
  43. public String getUserIdFromJwtToken(String token) {
  44. return Jwts.parserBuilder().setSigningKey(key()).build()
  45. .parseClaimsJws(token).getBody().getId();
  46. }
  47. public boolean isJWTExpired(String authToken) {
  48. Date expiresAt = getExpirationFromJwtToken(authToken);
  49. return expiresAt.before(new Date());
  50. }
  51. public boolean validateJwtToken(String authToken) {
  52. try {
  53. Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
  54. return true;
  55. } catch (MalformedJwtException e) {
  56. logger.error("Invalid JWT token: {}", e.getMessage());
  57. } catch (ExpiredJwtException e) {
  58. logger.error("JWT token is expired: {}", e.getMessage());
  59. } catch (UnsupportedJwtException e) {
  60. logger.error("JWT token is unsupported: {}", e.getMessage());
  61. } catch (IllegalArgumentException e) {
  62. logger.error("JWT claims string is empty: {}", e.getMessage());
  63. }
  64. return false;
  65. }
  66. }

字符串
以及登录认证控制器:

  1. @PostMapping("/signin")
  2. public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
  3. Authentication authentication = authenticationManager
  4. .authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getEmail(), loginRequest.getPassword()));
  5. SecurityContextHolder.getContext().setAuthentication(authentication);
  6. String jwt = jwtUtils.generateJwtToken(authentication);
  7. UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
  8. List<String> roles = userDetails.getAuthorities().stream().map(item -> item.getAuthority())
  9. .collect(Collectors.toList());
  10. User completeUser = userRepository.findById(userDetails.getId()).orElseThrow(() -> new ObjectNotFoundException(userDetails.getId(), "user"));
  11. RefreshToken refreshToken = refreshTokenService.createRefreshToken(userDetails.getId());
  12. return ResponseEntity
  13. .ok(new JwtResponse(jwt, refreshToken.getToken(), userDetails.getEmail(), roles, completeUser.getFirstName(), completeUser.getLastName(), completeUser.getHeight(), completeUser.getSex()));
  14. }


我有恼人的头痛这个错误。只是找不到解决方案。尝试了几个解决方案找到,但不工作。仍然说同样的错误。

ltskdhd1

ltskdhd11#

基本上,应该使用相同的键来生成JWT令牌并验证相同的JWT。
在令牌生成期间,您似乎使用了不同的密钥来对JWT进行签名(generateJwtToken)和验证(validateJwtToken)。在generateJwtToken中,您每次都使用Keys.secretKeyFor(SignatureAlgorithm.HS512)生成新的密钥,而在validateJwtToken中,您使用的是key(),它使用相同的算法生成新的密钥。要解决此问题,你应该使用相同的密钥来进行签名和验证。实现这一点的一种方法是将密钥作为一个字段存储在你的JwtUtils组件中并重用它。

相关问题