0

在这个示例之后,我编写了一些代码来验证来自 azure 的隐式流返回的访问令牌。

RemoteJWKSet remoteJWKSet = new RemoteJWKSet(new URL(jwksUri));
JWSKeySelector keySelector = new JWSVerificationKeySelector(JWSAlgorithm.RS256, remoteJWKSet);

ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor<>();

jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier(
      new JWTClaimsSet.Builder().issuer("https://sts.windows.net/3283e312-f73b-47d0-81c6-75e3ac726c21/").build(),
                new HashSet<>(Arrays.asList("sub", "iat", "exp", "scp"))));

jwtProcessor.setJWSKeySelector(keySelector);

JWTClaimsSet claimsSet = jwtProcessor.process(accessToken.getValue(), null);

但验证失败,我得到:

com.nimbusds.jose.proc.BadJWSException: Signed JWT rejected: Invalid signature
    at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:378)
    at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:303)
    at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:294)

我想我不需要DefaultJWTClaimsVerifier零件,但删除它不会改变任何东西。我应该保留它以坚持这个例子。

你知道为什么会这样吗?

谢谢你的帮助。

PS:无法使用 jwt.io 进行验证。我从 jwk 粘贴了 access_token 和“keys”部分的第一个条目。

4

1 回答 1

1

您需要expose an API scope在 Azure 中,并让客户端使用它。还要确保访问令牌的 JWT 标头中没有nonce字段。我的博客文章有更多信息。

天蓝色广告行为

上述行为是 Microsoft 特有的,在使用 Azure AD 作为提供程序时是必需的:

  • JWT 标头中带有 nonce 字段的令牌仅设计用于 MS API,例如 Graph,并使用内部验证机制。目的是让这些在自定义 API 中始终无法通过验证。

  • 您自己的自定义 API 的令牌必须通过请求自定义范围的客户端检索。请注意,在 Azure AD 中配置的 OAuth 客户端可以是一个逻辑条目,而不需要为每个单独的 API 维护一个。

我相信 MS 行为是基于OAuth 资源指标,尽管我个人的偏好是在 API 中接收访问令牌时使用更主流的范围声明和受众检查技术。

于 2022-03-01T19:30:01.037 回答