1

I am trying to verify a signature in Azure AD with Java:

<dependency>
  <groupId>com.microsoft.azure</groupId>
  <artifactId>azure-storage</artifactId>
  <version>8.6.6</version>
</dependency>
<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.18.2</version>
</dependency>
<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>jwks-rsa</artifactId>
  <version>0.19.0</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.12.5</version>
</dependency>

And If I try to verify a token, I receive the following error:

The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA

Applying the following method:

private boolean verifyJWT(String azureDiscoveryKeys, String token) {

    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);
        JWTVerifier verifier = JWT.require(alg).build();

        verifier.verify(token);

        return true;
    } catch(JWTVerificationException | JwkException | MalformedURLException ex) {
        System.out.println(ex.getMessage());
        return false;
    }
}

Testing the same method with a token provided by MS ADFS, I am able to verify but with Azure AD, I am not able. How to verify the token to avoid this error? How to adapt the code for Azure AD or to add support for SHA256withRSA? What is wrong in my code?

Many thanks in advance

Juan Antonio

jabrena
  • 1,166
  • 3
  • 11
  • 25
  • Where did you get the public keys from? What URL are you using to get the token? – juunas Sep 21 '21 at 09:28
  • Hi, I have used 3 different locations: String address = "https://login.microsoftonline.com/common/discovery/v2.0/keys"; String address = "https://login.microsoftonline.com/{tenantid}/discovery/keys"; String address = "https://login.microsoftonline.com/common/discovery/keys"; – jabrena Sep 21 '21 at 10:14
  • But I receive the same result – jabrena Sep 21 '21 at 10:15
  • Okay, I'm now wondering if you might be trying to validate an MS Graph API token :) What is the aud claim (audience) in the token if you decode it at e.g. https://jwt.ms? – juunas Sep 21 '21 at 10:56
  • "aud": "https://graph.microsoft.com", – jabrena Sep 21 '21 at 11:24

1 Answers1

1

You are trying to validate an access token meant for Microsoft Graph API. You should not do that, primarily because it is not meant for your app. They use something a bit different for signing and you can't use the same methods to validate Graph API tokens.

When acquiring tokens, make sure to use scopes defined by your application to receive a token for your app. That one you should be able to validate. If you also need to call MS Graph API, then you need to acquire two tokens.

juunas
  • 54,244
  • 13
  • 113
  • 149
  • It is true, I will review the scopes: curl --location --request POST 'https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id={clientId}' \ --data-urlencode 'client_secret={clientSecret}' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=https://graph.microsoft.com/.default openid email' – jabrena Sep 21 '21 at 13:06
  • Adding custom scopes for the application, I was able to fix the issue with any new line of code. Thanks @juunas, have a good day. – jabrena Sep 21 '21 at 15:03