我一直在为使用Spring Boot Security刷新令牌而苦苦挣扎.
在此之前,我已经使用JWT完成了工作身份验证,但现在当我创建这个刷新系统时,它不能再登录了.表示"JWT签名与本地计算的签名不匹配.无法断言JWT有效性,也不应信任它."我试图通过在这里和谷歌找到的不同主题来解决这个问题.
现在,我不能理解这种情况,错误来自哪里.I在JWT验证方法上崩溃:
JwtUtils.java
package com.testapp.springbooot.security.jwt;
import java.security.Key;
import java.util.Date;
import com.testapp.springbooot.security.services.UserDetailsImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${testapp.app.jwtSecret}")
private String jwtSecret;
@Value("${testapp.app.jwtExpirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setId("" + userPrincipal.getId())
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(key(), Signature算法rithm.HS512)
.compact();
}
private Key key() {
return Keys.secretKeyFor(Signature算法rithm.HS512);
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parserBuilder().setSigningKey(key()).build()
.parseClaimsJws(token).getBody().getSubject();
}
public String getEmailFromJwtToken(String token) {
return Jwts.parserBuilder().setSigningKey(key()).build()
.parseClaimsJws(token).getBody().getSubject();
}
public Date getExpirationFromJwtToken(String token) {
return Jwts.parserBuilder().setSigningKey(key()).build()
.parseClaimsJws(token).getBody().getExpiration();
}
public String getUserIdFromJwtToken(String token) {
return Jwts.parserBuilder().setSigningKey(key()).build()
.parseClaimsJws(token).getBody().getId();
}
public boolean isJWTExpired(String authToken) {
Date expiresAt = getExpirationFromJwtToken(authToken);
return expiresAt.before(new Date());
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
return true;
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
以及登录认证控制器:
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getEmail(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream().map(item -> item.getAuthority())
.collect(Collectors.toList());
User completeUser = userRepository.findById(userDetails.getId()).orElseThrow(() -> new ObjectNotFoundException(userDetails.getId(), "user"));
RefreshToken refreshToken = refreshTokenService.createRefreshToken(userDetails.getId());
return ResponseEntity
.ok(new JwtResponse(jwt, refreshToken.getToken(), userDetails.getEmail(), roles, completeUser.getFirstName(), completeUser.getLastName(), completeUser.getHeight(), completeUser.getSex()));
}
这个错误让我头疼得要命.就是找不到解决办法.try 了几个解决方案,但没有奏效.仍然说着同样的错误.