SpringSecurity整合JWT一些異常了解及處理io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature解決及UnsupportedJwtException:Signed Claims JWSs are not supported


一、問題背景及解決方案

  SpringBoot整合SpringSecurity整合都正常。但是就是偶爾時不時有個報錯,貌似不影響功能,但是很煩。具體報錯如下:

io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. 
JWT validity cannot be asserted and should not be trusted.

  說的意思是:io.jsonwebtoken.SignatureException:JWT簽名與本地計算的簽名不匹配。JWT有效性不能斷言,也不應被信任。

  因為有多個項目,所以猜測可能是 token 串了的原因。

  最后的解決方案是加了一些catch異常,加了之后,就沒有報錯了。

public class JWTAuthenticationFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { // 可以取到用戶信息的(有正確token)將用戶信息放入上下文
        try { Authentication auth = TokenAuthenticationService.getAuthentication((HttpServletRequest) request, (HttpServletResponse) response); SecurityContextHolder.getContext().setAuthentication(auth); } catch (MalformedJwtException | SignatureException | ExpiredJwtException | UnsupportedJwtException e) { SecurityContextHolder.getContext().setAuthentication(null); } finally{ filterChain.doFilter(request, response); } } }

  標粗的四個異常就是加的。

二、jwt幾種異常的了解和分析

1、MalformedJwtException

  這種異常說的是 token 格式不對。有時候會報這樣的錯:

io.jsonwebtoken.MalformedJwtException: JWT strings must contain exactly 2 period characters. Found: // io.jsonwebtoken.MalformedJwtException:JWT字符串必須正好包含2個句點字符。找到:

2、SignatureException

  這種異常說的是 token 簽名不對。比較好理解,比如:

public static void addAuthentication(HttpServletResponse res, String username, String role) {   String JWT = Jwts.builder()     .setSubject(username)     .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))     .claim("roleName", role)     .signWith(SignatureAlgorithm.HS512, SECRET)     .compact();   res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT); }
// parse the token.
Claims body = Jwts.parser()   .setSigningKey(SECRET)   .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))   .getBody(); String username = body.getSubject();

  如果生成 token 和解析 token 使用的 SECRET 簽名不一致就會報這個錯誤。

  所以再看上面問題的報錯,就很明顯了,就是token的簽名不對。

3、ExpiredJwtException

  這種異常就是 token 過期了報的異常。

4、UnsupportedJwtException

  這種異常就是不支持的 Jwt 報的異常。

  加了以上4種異常捕獲,然后在 上下文 中將當前用戶設為 null 即可,那么就相當於一個游客訪問項目了。

  其實以上異常根據字面意思就很好理解:Malformed:格式不正確、Signature:簽名、Expired:期滿(過期)、Unsupported:不支持的。

三、jwt驗證token報錯:io.jsonwebtoken.UnsupportedJwtException: Signed Claims JWSs are not supported的解決

  這個是網上查相關資料時看的,因為我一直用的都是正確的 parseClaimsJws ,但是也記錄一下,有個印象。

  報錯信息:

io.jsonwebtoken.UnsupportedJwtException: Signed Claims JWSs are not supported. at io.jsonwebtoken.JwtHandlerAdapter.onClaimsJws(JwtHandlerAdapter.java:50) at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:487) at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJwt(DefaultJwtParser.java:514) at com.glzt.test.util.JwtUtils.getClaimsFromToken(JwtUtils.java:120) at com.glzt.test.util.JwtUtils.memoryUserInRedis(JwtUtils.java:185) at com.glzt.test.util.JwtUtils.generateToken(JwtUtils.java:162) at com.glzt.test.util.JwtUtils.generateToken(JwtUtils.java:148)
// 錯誤寫法:parseClaimsJwt
Jwts.parser().setSigningKey(SECRET).parseClaimsJwt(token.replace(TOKEN_PREFIX, "")).getBody(); // 正確寫法:parseClaimsJws
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM