Note: The values that used in this question are only sample. E.g.: 3d355765-XXX-47cd-9c7a-bf31179f5XXX
Hello everyone, I have a ReactJS application and a Spring backend application. However, Backend Application cannot verify token and it throws "The Token’s Signature resulted invalid when verified using the Algorithm: SHA256withRSA" exception.
Could you please help me to find the reason?
Azure Entra Configuration
In Azure Entra, I only configured this "Authentication" configuration for ReactJS application:
ReactJS Configuration
ReactJS application successfully can get access token from Azure OIDC.
react-oidc-context library is used.
Here is ReactJS configuration:
Spring Backend Configuration With Auth0 Library
I use access_token
in header with "Bearer" prefix when I send request to backend application. An example: "Bearer eyJ0eXAiOiJKV1QiL….". I can handle that access token. The problem is that I cannot verify it with the publicKey
that is obtained from JWK URL.
Libraries
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>jwks-rsa</artifactId>
<version>0.22.1</version>
</dependency>
Implementation
DecodedJWT jwt = JWT.decode(token);
JwkProvider provider = new UrlJwkProvider(new URL("https://login.microsoftonline.com/3d355765-XXX-47cd-9c7a-bf31179f5XXX/discovery/v2.0/keys?appid=5b20cc33-a01b-XXX-be31-cd9ff3aa7XXX"));
Jwk jwk = provider.get(jwt.getKeyId());
Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
algorithm.verify(jwt);
Library creates this public key:
Sun RSA public key, 2048 bits
params: null
modulus: 26737083189757907003055921442770314338988917140860165426744103322405302728616784576359656902377694864963514916366447987755596040063091127319443429395704125552922128507194605677562878395533638591796237899749004909932248262554836300040575758977279732502744063204426839357267389987189285837088487291113549843075686248327277545438158623612248961469127033882959503541559213717818450130719611600764540097268466124320654392000567544359397082999966622432696244505348004947998457969327542701030616111112222267178710534245286750373749139781560960689184289029103448294950355123548539876783713876691492097395497625781588902647221
public exponent: 65537
Backend application throws this error at algorithm.verify(jwt);
step:
I still don’t understand what is missing.
Do you think is there some missing configuration in Azure Entra, ReactJS application or Spring Backend application?
Additional Information
When I use jsonwebtoken
library insed of auth0
library:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
I implemented backend application like this:
Jwts.parserBuilder()
.setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public Key resolveSigningKey(io.jsonwebtoken.JwsHeader header, Claims claims) {
String jwksUrl = "https://login.microsoftonline.com/3d355765-XXX-47cd-9c7a-bf31179f5XXX/discovery/v2.0/keys?appid=5b20cc33-a01b-XXX-be31-cd9ff3aa7XXX";
String kid = header.getKeyId();
log.info("kid value: {}", kid);
try {
String jwksJson = JWKSFetcher.getJWKS(jwksUrl);
log.info("jwksJson value: {}", jwksJson);
return PublicKeyExtractor.getPublicKeyFromJWKS(jwksJson, kid);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
})
.build()
.parseClaimsJws(token)
.getBody();
The jsonwebtoken
library throws this exception:
JWT signature does not match locally computed signature. JWT validity
cannot be asserted and should not be trusted.
AN UPDATE: "ISSUER IS DIFFERENCES" (06.08.2024)
Today, I noticed there is issuer differences. Could it be a cause of the my problem?
I obtained the token from https://login.microsoftonline.com/{{MY_TENANT_ID}}/v2.0
The issuer in the token that comes back is https://sts.windows.net//{{MY_TENANT_ID}}/ which doesn’t match.
When I check the config at .well-known/openid-configuration the issuer is as expected https://login.microsoftonline.com/{{MY_TENANT_ID}}//v2.0
And also, JWKS endpoint returns this issuer: https://login.microsoftonline.com/{{MY_TENANT_ID}}//v2.0
I updated manifest file:
But, unfortunately I still get token with v1.0:
AN UPDATE: "Cannot Verify Access_Token but Id_Token Works" (09.08.2024)
I know that it shouldn’t be and it is strange but, while the backend application cannot verify access_token
and getting ‘Signature verification failed" exception, in the other hand, it can verify the id_token
.
2
Answers
Note that, open_id and offline_access are Microsoft Graph scopes which generates token with aud as
00000003-0000-0000-c000-000000000000
that gives "Invalid Signature" error when you validate it.To resolve that, you need to expose API by creating custom scopes and generate token with those custom scopes.
For sample, I exposed an API in an app registration and created custom scopes in it as below:
Make sure to change "requestedAccessTokenVersion" to 2 in App’s Manifest for generating access token of version 2.0 :
Now, I added these
API permissions
and granted consent in application from which token will be generated like this:Initially, I ran below authorization request in browser and got
code
value in address bar after successful authentication:Later, I generated access token using authorization code with PKCE flow via Postman like this:
Response:
When I decoded this token in jwt.io, signature verified successfully and token generated with version 2.0 as below:
In your case, expose an API by creating new custom scope and use those new custom scope values in
ssoScopes
parameter while generating the access token.Make sure not to pass Microsoft Graph scopes like openid or offline_access in
ssoScopes
parameter.Reference:
java – Azure OAuth2: can’t validate access token – Stack Overflow by me
I found a blog that helped me understand this issue. Please check the problem part https://xsreality.medium.com/making-azure-ad-oidc-compliant-5734b70c43ff