java - Azure 针对 Azure B2C 活动目录验证 JWT 令牌
问题描述
电话客户端向我发送从 Azure 中的 Active Directory B2C 获取的 access_token。我有一个服务器端 Spring Boot 应用程序,想检查令牌的来源是否是 Azure 的 Active Directory,并且不是手动操作的,它是否有效。
我期待类似的东西
String validationUrl = "https://azure.microsoft/validate-token";
// put token in header
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> entity = new HttpEntity<>(null, headers);
String result = restTemplate.exchange(validationUrl, HttpMethod.GET,
entity, String.class).getBody();
我尝试了类似于:
try {
provider = new UrlJwkProvider(new URL("https://login.microsoftonline.com/common/.well-known/openid-configuration"));
jwk = provider.get(jwt.getKeyId());
algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
algorithm.verify(jwt);// if the token signature is invalid, the method will throw SignatureVerificationException
return true;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (JwkException e) {
e.printStackTrace();
} catch (SignatureVerificationException e) {
System.out.println(e.getMessage());
}
结果总是 com.auth0.jwk.SigningKeyNotFoundException: No keys found in
然后我尝试了另一种实现:
HttpsJwks httpsJkws = new HttpsJwks(url);
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(3600) // allow some leeway in validating time based claims to account for clock skew
.setVerificationKeyResolver(httpsJwksKeyResolver)
.setRelaxVerificationKeyValidation()
.build();
try
{
// Validate the JWT and process it to the Claims
JwtClaims jwtClaims = jwtConsumer.processToClaims(accessToken);
System.out.println("JWT validation succeeded! " + jwtClaims);
return true;
}
catch (InvalidJwtException e)
{
// InvalidJwtException will be thrown, if the JWT failed processing or validation in anyway.
// Hopefully with meaningful explanations(s) about what went wrong.
System.out.println("Invalid JWT! " + e);
}
结果总是无效的 JWT!org.jose4j.jwt.consumer.InvalidJwtException:JWT 处理失败。其他详细信息:[[17] 无法处理 JOSE 对象(原因:org.jose4j.lang.UnresolvableKeyException:无法为带有标头的 JWS 找到合适的验证密钥
我还尝试了以下 URL: https ://login.microsoftonline.com/MY_TENANT/.well-known/openid-configuration
https://login.microsoftonline.com/MY_TENANT/discovery/v2.0/keys?appid=APP_ID
https://login.microsoftonline.com/MY_TENANT/discovery/v2.0/keys
https://login.microsoftonline.com/common/.well-known/openid-configuration
解决方案
Azure AD 的 access_token 是 JSON Web Token (JWT)。因此,您可以使用 Java 中的 JWKS 验证 JWT 令牌。jwks_uri
可以通过形成的链接获取/.well-known/openid-configuration
,见这里。
DecodedJWT jwt = JWT.decode(token);
JwkProvider provider = provider = new UrlJwkProvider("https://login.microsoftonline.com/common/discovery/keys");
Jwk jwk = provider.get(jwt.getKeyId());
Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
algorithm.verify(jwt);
您可以先在线测试您的令牌,https://jwt.io/。
推荐阅读
- c# - 在 openpop net 中阅读电子邮件时收到错误“输入不是有效的 base64 字符串,因为它包含非 base 64 字符”
- java - 在 android gradle 项目中将 java 编译器标志添加到除协议缓冲区之外的所有内容
- php - 通过 packagist 打包一个 forked composer
- html - 将加载器与页面中心对齐并向其添加文本
- php - 如何在 postgresql 中保存二进制类型
- reactjs - 如何在使用reactjs单击复选框时禁用输入字段
- cmake - 等待 CMake 构建中的目标
- c++ - 从用户那里获取 N 个数字并找到最大的
- python - 通过多个线程将数据写入一个文件
- d3.js - 如何使元素根据其值将其自身放置在条形顶部?