Java验证Azure AD签名时出现SHA256withRSA无效错误如何解决
问题原因
签名无效报错主要有3个常见触发场景:
- JWKS discovery地址与令牌发行版本不匹配:Azure AD v1.0和v2.0端点的公钥存储地址完全独立,混用会导致拿到的公钥与签名不匹配。
- 验证的令牌不符合校验要求:如果你校验的是面向Microsoft Graph、Azure存储等微软官方服务签发的访问令牌,这类令牌的签名密钥不对外公开,无法通过公开JWKS地址拿到的公钥完成校验。
- 缺少Azure AD强制要求的声明校验规则,部分版本的auth0 jwt库在校验逻辑中会隐式关联声明校验结果,最终抛出签名无效的异常。
适配调整方案
前置排查
- 确认令牌发行版本:如果是v1.0端点签发的令牌,使用格式为
https://login.microsoftonline.com/{租户ID}/discovery/keys的JWKS地址;如果是v2.0端点签发的令牌,使用格式为https://login.microsoftonline.com/{租户ID}/discovery/v2.0/keys的JWKS地址,两者不可混用。 - 确认校验的令牌是id_token,或者是面向你自己注册的API签发的访问令牌:需要让请求令牌的客户端将scope指定为你注册的API的scope,才能拿到可正常校验的访问令牌。
代码调整
修改后的代码增加了Azure AD要求的发行者、受众校验逻辑,同时补充了排查日志,方便定位问题:
private boolean verifyJWT(String azureDiscoveryKeys, String token, String expectedIssuer, String expectedAudience) { try { JwkProvider provider = new UrlJwkProvider(new URL(azureDiscoveryKeys)); DecodedJWT jwt = JWT.decode(token); Jwk jwk = provider.get(jwt.getKeyId()); RSAPublicKey publicKey = (RSAPublicKey) jwk.getPublicKey(); Algorithm alg = Algorithm.RSA256(publicKey, null); // 补充Azure AD要求的声明校验 JWTVerifier verifier = JWT.require(alg) .withIssuer(expectedIssuer) .withAudience(expectedAudience) .build(); verifier.verify(token); return true; } catch(JWTVerificationException | JwkException | MalformedURLException ex) { // 输出完整堆栈便于定位具体错误点 ex.printStackTrace(); return false; } }
参数补充说明:
- expectedIssuer格式:v1端点为
https://sts.windows.net/{租户ID}/,v2端点为https://login.microsoftonline.com/{租户ID}/v2.0 - expectedAudience为你在Azure AD注册的应用客户端ID,或自定义的API应用ID URI
内容的提问来源于stack exchange,提问作者jabrena
相关产品推荐
相关产品推荐

