JwtSignatureException是Spring Security在JWT签名验证失败时抛出的标准异常,由JwtDecoder自动触发或手动封装,需确保密钥一致、算法匹配,并避免日志泄露token明文。

<p>JWT 签名验签失败时抛出 <code>JwtSignatureException</code>,核心在于捕获底层签名验证异常并主动封装为 Spring Security 提供的标准异常类型。</p>
<H3>使用 JwtDecoder 时自动抛出 JwtSignatureException</H3>
<p>Spring Security 5.7+ 的 <code>JwtDecoder</code>(如 <code>NimbusJwtDecoder</code>)在签名验证失败时,默认就会抛出 <code>JwtSignatureException</code>,无需手动 throw。只要配置正确,框架会自动处理:</p>
<ul>
<li>确保使用的是 <code>NimbusJwtDecoder</code> 或支持签名验证的实现</li>
<li>密钥(<code>SecretKey</code> 或 <code>RSAKey</code>)必须与签发时一致,且未被篡改</li>
<li>JWT header 中的 <code>alg</code> 值(如 HS256、RS256)需与解码器预期匹配</li>
</ul>
<H3>手动验证 JWT 并显式抛出 JwtSignatureException</H3>
<p>若需自定义校验逻辑(例如预处理 token、多密钥路由),可调用 <code>JwtDecoder#decode</code> 并捕获异常后重新抛出:</p>
<pre><code>try {
Jwt jwt = jwtDecoder.decode(token);
} catch (JwtValidationException ex) {
// Nimbus 抛 JwtValidationException,含签名失败原因
throw new JwtSignatureException("Invalid signature", token, ex);
} catch (RuntimeException ex) {
// 其他运行时异常(如解析失败、过期等)不一定是签名问题
if (ex instanceof JwtSignatureException) {
throw ex;
}
throw new JwtSignatureException("Signature verification failed", token, ex);
}</code></pre>
<H3>自定义 JwtDecoder 包装异常</H3>
<p>若想统一拦截所有签名失败场景,可包装原始 decoder:</p>
<ul>
<li>继承 <code>AbstractJwtDecoder</code> 或装饰 <code>JwtDecoder</code></li>
<li>重写 <code>decode</code> 方法,在 catch <code>JwtValidationException</code> 时判断是否由签名引起(检查 cause 是否为 <code>SignatureException</code> 或消息含 "signature")</li>
<li>仅对签名类错误构造 <code>JwtSignatureException</code>,其他保留原异常</li>
</ul>
<H3>注意异常链和日志敏感信息</H3>
<p><code>JwtSignatureException</code> 构造时传入的 token 字符串不应直接打到日志(避免泄露敏感凭证):</p>
<ul>
<li>建议只记录 token 头部(前 20 字符)或哈希摘要</li>
<li>异常 message 可写 "Invalid JWT signature",不暴露算法或密钥细节</li>
<li>确保全局异常处理器(如 <code>@ControllerAdvice</code>)对 <code>JwtSignatureException</code> 返回 401,并隐藏堆栈中密钥相关线索</li>
</ul>