azureazure-active-directorymicrosoft-entra-id

on-behalf-of flow, getting error AADSTS50013 while acquiring obo token


So basically I want to achieve the following:

enter image description here

Obviously, as the title states, this gives me issues - basically I'm getting the following error upon trying to get the OBO token on behalf of the user.

{
"error": "invalid_grant",
"error_description": "AADSTS50013: Assertion failed signature validation. [Reason - Key was found, but use of the key to verify the signature failed., Thumbprint of key used by client: 'XXXX', Found key 'Start=11/27/2024 09:04:39, End=11/27/2029 09:04:39', Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for app Id 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx'. 
... 
}

In the API app registration, I have done the following in Azure:

In the SPA app registration, I have done the following in Azure:

When I request the access token for the user, I notice that the audience assumes the following form:

"aud": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx",

rather than:

"aud": api://ID_OF_THE_API_ENDPOINT

I'm not sure if this is correct, nor do I know how I can get the correct audience, if it's incorrect.

When I'm requesting the OBO token in postman, I'm doing the following:

GET: https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token

Body:

I have been over this multiple times, but I really can't seem to grasp what I'm missing.


Solution

  • I registered one API app registration and exposed an API by authorizing SPA client application with access_as_user scope:

    enter image description here

    In client SPA app registration, I added above custom API permission with consent like this:

    enter image description here

    For user access token, I used authorization code flow with PKCE that can be used as assertion value in OBO flow.

    Initially, I ran below authorization request in browser and got code value in address bar after successful authentication:

    https://login.microsoftonline.com/tenantId/oauth2/v2.0/authorize?
    client_id=SPAappId
    &response_type=code
    &redirect_uri=https://jwt.ms
    &response_mode=query
    &scope= api://xxxxxxxx/access_as_user
    &code_challenge=xxxxxxxxx
    &code_challenge_method=S256
    

    enter image description here

    Now, I used this code to generate access token using PKCE flow with below parameters via Postman:

    POST https://login.microsoftonline.com/tenantId/oauth2/v2.0/token
    
    grant_type:authorization_code
    client_id:ClientSPAappId
    scope: api://xxxxxxxx/access_as_user
    code: <paste_code_from_above_step>
    code_verifier:S256
    redirect_uri: https://jwt.ms
    

    enter image description here

    For acquiring on-behalf-of flow access token to call Microsoft Graph, I used below parameters via Postman:

    POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
    
    client_id:APIappID
    client_secret:APIappSecret
    scope: https://graph.microsoft.com/User.Read
    grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer
    assertion:<paste_token_from_above_step>
    requested_token_use:on_behalf_of
    

    enter image description here

    You can now use this OBO token to call Microsoft Graph API as below:

    GET https://graph.microsoft.com/v1.0/me/
    

    enter image description here

    Reference:

    Access user info from azure access token - Stack Overflow