Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid signature while validating Azure ad access token, but id token works

I am getting invalid signature while using jwt.io to validate my azure ad access token. My id token, however, validates just fine!

I have seen and tried the solutions suggested in
Invalid signature while validating Azure ad access token
and
https://nicksnettravels.builttoroam.com/post/2017/01/24/Verifying-Azure-Active-Directory-JWT-Tokens.aspx
but neither works for my access token.

The access and Id token is generated via Adal.js:

    var endpoints = {
        "https://graph.windows.net": "https://graph.windows.net"
    };
    var configOptions = {
        tenant: "<ad>.onmicrosoft.com", // Optional by default, it sends common
        clientId: "<app ID from azure portal>",
        postLogoutRedirectUri: window.location.origin,
        endpoints: endpoints,
    }
    window.authContext = new AuthenticationContext(configOptions);

Why can I validate my ID token, but not my access token?

like image 571
Jeppe Avatar asked Jul 26 '17 03:07

Jeppe


People also ask

What is ID token in Azure?

ID tokens are JSON web tokens (JWT). These ID tokens consist of a header, payload, and signature. The header and signature are used to verify the authenticity of the token, while the payload contains the information about the user requested by your client.


2 Answers

Please refer to thread : https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609

but if look at the Jwt.Header you will see a 'nonce'. This means you need special processing. Normal processing will fail.

So if nonce includes in access token , validate signature with JWT.io or JwtSecurityToken won't success .

like image 58
Nan Yu Avatar answered Jan 03 '23 23:01

Nan Yu


Thanks to Nan Yu I managed to get token that can be validated by any public jwt validator like jwt.io (couldn't put my comment in the comments section under Nan Yu's answer because its too long).

So as I understand the point from the discussion mentioned by Nan Yu that by default Azure AD generates tokens for Microsoft Graph and these tokens use special signing mechanism so that it is not possible to validate signature using public validators (except jwt.ms Microsoft's validator which most probably knows what mysterious special handling means :) ).

To get access token not for Microsoft Graph that can be validated using public validators I had to:

  • Remove any Microsoft Graph related scopes (by default I had only one scope configured User.Read so removed it in appConfig > API permissions)
  • create a custom scope for your application (appConfig > Expose an API > Add scope ...) this scope will look like api://{application-id}/scope-name
  • add just created scope in the application API permissions (appConfig > API permissions > Add api permission > My APIs > select your application > Delegated Permissions > Check your scope > Add permission)
  • then use this scope in your openid client scopes, in my case I have: openid offline_access {application-id}/scope-name

Note that in the openid client config newly created scope is used without api:// prefix (offline_access I have to enable refresh_token can be ignored if refresh token mechanism is not used)


like image 21
Oleh Avatar answered Jan 03 '23 23:01

Oleh