Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Error verifying access token from Azure active directory : steps.jwt.InvalidToken : Invalid token:

We use Azure AD tokens as well. We have the following policies in place to do this:

1.Service callout to get token from azure:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="GetAccessToken">
    <DisplayName>GetAccessToken</DisplayName>
    <Properties/>
    <Request clearPayload="true" variable="oauthRequest">
<Headers>
<Header name="Content-Type">application/x-www-form-urlencoded</Header>
</Headers>
<FormParams>
<FormParam name="client_id">*********</FormParam>
<FormParam name="client_secret">***************</FormParam>
<FormParam name="grant_type">client_credentials</FormParam>
<FormParam name="scope">https://graph.microsoft.com/.default</FormParam>
</FormParams> <Set> <Verb>POST</Verb> </Set> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </Request> <Response>calloutResponse</Response> <HTTPTargetConnection> <Properties/> <URL>https://login.microsoftonline.com/XXXX-TENNANTID-XXXX/oauth/v2.0/token</URL> </HTTPTargetConnection> </ServiceCallout>

I get the access token successfully.
I have even tried using "https://login.microsoftonline.com/common/discovery/v2.0/keys"
But it got keys and it failed in validation

2. Retrieve keys from MS:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="SC-RetrieveMicrosoftKeys">
    <DisplayName>SC-RetrieveMicrosoftKeys</DisplayName>
    <Properties/>
    <Request clearPayload="true" variable="myRequest">
        <Set>
            <Verb>GET</Verb>
        </Set>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    </Request>
    <Response>msKeys</Response>
    <HTTPTargetConnection>
        <Properties/>
        <URL>https://login.microsoftonline.com/XXXX-TENNANTID-XXXX/discovery/v2.0/keys</URL>
    </HTTPTargetConnection>
</ServiceCallout>

I recieve the keys success fully

2. Extract JWT from header:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables name="Extract-JWT-Assign-Message" enabled="true" async="false" continueOnError="false">
    <Source>calloutResponse</Source>
    <JSONPayload>
<Variable name="access_token">$.access_token</Variable>
</JSONPayload> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> </ExtractVariables>

Access_token is extracted successfully
3. Verify JWT:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyJWT async="false" continueOnError="true" enabled="true" name="VerifyJWT">
    <DisplayName>VerifyJWT</DisplayName>
    <Algorithm>RS256</Algorithm>
    <Source>authn.jwt</Source>
    <PublicKey>
        <JWKS ref="msKeys.content"/>
    </PublicKey>
    <Issuer>https://sts.windows.net/XXXX-TENNANTID-XXXX/</Issuer>
    <Audience ref="aud"/>
    <AdditionalClaims>
        <Claim name="roles" ref="active-directory.jwt.roles" type="string" array="true"/>
    </AdditionalClaims>
</VerifyJWT>

 Here I get error saying 

{
    "fault": {
        "faultstring": "Invalid token: policy(Verify-JWT-1)",
        "detail": {
            "errorcode": "steps.jwt.InvalidToken"
        }
    }
}

 

Solved Solved
0 3 688
1 ACCEPTED SOLUTION

I guess you are facing this problem , which is not a problem in Apigee, nor is it a problem in Azure per se, but rather, a misunderstanding of the token Azure creates and hands out to you. In my opinion the misunderstanding is Microsoft's fault, because ...  they could have been clearer. But I guess that's irrelevant when you 're just trying to solve the problem.

When you request a token from Entra ID with a scope of https://graph.microsoft.com/.default, you get a token that looks like a JWT, and can be decoded in the same way a JWT can be decoded, but it cannot be verified like a JWT. Despite appearances, it is not actually a JWT, so VerifyJWT will never work to "verify it".   If that seems confusing to you, you are not alone. I find it confusing too. And that's the part I think Microsoft is responsible for. You can read in more detail than you probably want, here.

The solution is one of these two things:

When you use the special scope of https://graph.​microsoft.com/.default , you're telling Azure AD (Entra ID):  I want you to issue a token that will be used for the Graph API. That token looks-like-a-JWT-but-is-not.  You should not try to verify it.  Any necessary verification will be performed by Microsoft, when you present that token when invoking the graph API.

 

View solution in original post

3 REPLIES 3
Top Solution Authors