英文:
Azure validating a JWT Token against the Azure B2C active directory
问题
A phone client sends me an access_token acquired from Active Directory B2C in Azure.
我收到了来自Azure中的Active Directory B2C获取的access_token的电话客户端。
I have a server-side Spring Boot Application and want to check if the token's source is the Active Directory from Azure and was not manipulated by hand and it is valid.
我有一个运行在服务器端的Spring Boot应用程序,希望检查token的来源是否是来自Azure的Active Directory,并且没有手动篡改,且有效。
I am expecting something like
我期望的是类似于以下的代码:
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();
I tried implementation similar to :
我尝试了类似以下的实现:
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());
}
The result was always com.auth0.jwk.SigningKeyNotFoundException: No keys found in
然而结果总是com.auth0.jwk.SigningKeyNotFoundException: 未找到密钥
Then I tried another implementation :
然后我尝试了另一种实现:
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);
}
The result was always Invalid JWT! org.jose4j.jwt.consumer.InvalidJwtException: JWT processing failed. Additional details: [[17] Unable to process JOSE object (cause: org.jose4j.lang.UnresolvableKeyException: Unable to find a suitable verification key for JWS w/ header
然而结果总是Invalid JWT! org.jose4j.jwt.consumer.InvalidJwtException: JWT处理失败。附加细节:[[17] 无法处理JOSE对象 (原因: org.jose4j.lang.UnresolvableKeyException: 无法找到适用于JWS w/ header的合适的验证密钥
I have tried also following URLs:
我还尝试了以下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
https://login.microsoftonline.com/discovery/v2.0/keys
英文:
A phone client sends me an access_token acquired from Active Directory B2C in Azure.
I have a server-side Spring Boot Application and want to check if the token's source is the Active Directory from Azure and was not manipulated by hand and it is valid.
I am expecting something like
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();
I tried implementation similar to :
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());
}
The result was always com.auth0.jwk.SigningKeyNotFoundException: No keys found in
Then I tried another implementation :
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);
}
The result was always Invalid JWT! org.jose4j.jwt.consumer.InvalidJwtException: JWT processing failed. Additional details: [[17] Unable to process JOSE object (cause: org.jose4j.lang.UnresolvableKeyException: Unable to find a suitable verification key for JWS w/ header
I have tried also following URLs:
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
答案1
得分: 4
Azure AD的access_token是JSON Web Token(JWT)。因此,您可以使用Java验证JWT令牌,使用JWKS。jwks_uri
可以通过形成的链接获得,链接形式为/.well-known/openid-configuration
,请参见这里。
DecodedJWT jwt = JWT.decode(token);
JwkProvider 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/。
英文:
The access_token of Azure AD is a JSON Web Token(JWT). So you could validate JWT tokens using JWKS in Java. jwks_uri
can be acquired by the link that formed as /.well-known/openid-configuration
, see here.
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);
You could test your token online first, https://jwt.io/.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论