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();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2017-06-23 iframe多层嵌套时获取元素