Background

Microsoft Azure Active Directory supports an OAuth2 protocol extension called On-Behalf-Of flow (OBO flow). This is documented at both the Microsoft Identity Platform V1 and V2 endpoint. The OBO flow is used in the following scenario. Both Web API 1 and Web API 2 are protected by Azure AD.

  1. A client application (could be a SPA app, a front-end Web Application, or a native application) signs a user into Azure AD and request a delegated access token for Web API 1
  2. Client application then calls Web API 1 with the issued access token
  3. Web API 1 in turn needs to call a downstream Web API 2 so it uses its access token (in step 2 above) to request an access token for Web API 2. What happens in this step is that Web API 1 uses the OBO flow to exchange its access token for another resource’s access token. The exchanged token is still issued on behalf of the original sign in user and it has delegated permission.
  4. Web API 2 uses the new access token to call Web API 2

Let’s look at the parameters used in an OBO flow at the V1 endpoint below. I want to call out a few highlighted parameters as their significance will become more obvious a little bit later.

assertion:
this is the access token issued in step 2 above

client_id:
application id of Web API 1

Resource:
this is Application ID URI or Application ID of Web API 2

Let’s look at an OBO end to end traffic in Fiddler:

Frame 1 – 14 below shows the user navigates to the web site and is redirected to Azure AD to log in. Frame 15 is the request to the token endpoint to get an access token for Web API 1

Hover over image to enlarge

In this example Web API 2 is Microsoft Graph. In frame 19 below Web API 1 uses an OBO flow to request a token for Microsoft Graph. It uses the access token received in frame 15 as the assertion parameter.

Hover over image to enlarge

It is extremely important to use the correct parameter in the OBO flow. Note that the OBO parameters client_id and the assertion (access token) are for the calling application (Web API 1) in this token exchange request.

Common pitfall customers run into when using the OBO flow

I have seen a few AADSTS error returned for this flow when either the client_id or the assertion parameters used are not for the calling application (Web API 1). Below are a few examples:

HTTP 400 error: AADSTS500131: Assertion audience does not match the Client app presenting the assertion. The audience in the assertion was ‘00000002-0000-0000-c000-000000000000’ and the expected audience is …

Root cause: The access token used in the assertion is for a different application / resource instead of for the calling app Web API 1. The GUID in this error is an Azure AD Graph resource.

HTTP 400 error: AADSTS50013: Assertion failed signature validation. [Reason – The provided signature value did not match the expected signature value., Thumbprint of key used by client:…

Root cause: The access token used in the assertion is for Microsoft Graph resource (https://graph.microsoft.com)

HTTP 400 error: AADSTS50013: Assertion failed signature validation. [Reason – The key was not found., Thumbprint of key used by client: ‘B25930C…..
Root cause: Web API 1 is a SAML Application (check the Enterprise Application blade to see if Single sign-on is enabled and there is a SAML signing Certificate attached).

HTTP 500 error: AADSTS50000: There was an error issuing a token.

Root cause: the client id used is either not valid or does not exist in the tenant.

How can I diagnose this issue?

  • Take a Fiddler trace to see what the parameters used are.
  • Use https://jwt.ms to decode the access token assertion and look at the “aud” (audience) claim to see if it’s for the calling web API 1

What if my Web API 2 is SAML Application?

If the downstream API App can only consume SAML token (instead of jwt token), you can certainly use the OBO flow to exchange a JWT token for the SAML token using the following parameters (see https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow for more info). The key is in the parameter requested_token_type. The allowed values are

urn:ietf:params:oauth:token-type:saml2 – SAML 2.0 token

urn:ietf:params:oauth:token-type:saml1 – SAML 1.1 token

Note:
this JWT – SAML token exchange OBO flow is only available in the V1 endpoint since the V2 endpoint does not support SAML token. See https://docs.microsoft.com/en-us/azure/active-directory/develop/azure-ad-endpoint-comparison for more info

What about Azure AD B2C?

The OBO flow is currently not supported in Azure AD B2C per https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-apps#web-api-chains-on-behalf-of-flow

Drop me a comment if you find this useful or any other important information I should add.

==========

Update 8/22 – added one more condition for error AADSTS50013 due to SAML App

15
Leave a Reply

avatar
2 Comment threads
13 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
Bac Hoang [MSFT]NikhilMárcio LaubsteinMárcio Masculino LaubsteinMARCIO FELIPE LAUBSTEIN Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
MARCIO FELIPE LAUBSTEIN
Guest
MARCIO FELIPE LAUBSTEIN

Great article, I am trying to get a saml token from a jwt token but when i hit the endpoint to get the saml token i am receiving the following error: { “error”: “invalid_grant”, “error_description”: “AADSTS50013: Assertion failed signature validation. [Reason – The key was not found., Thumbprint of key used by client: ‘CAC25D36924A3AD5B1D66E884AA55B5F04526F1A’]\r\nTrace ID: 47644c95-3bd8-46c3-b320-23fbe9432c00\r\nCorrelation ID: 5e83afde-3791-4d87-bce2-dfe5dc5d4ee6\r\nTimestamp: 2019-08-21 00:33:27Z”, “error_codes”: [ 50013 ], “timestamp”: “2019-08-21 00:33:27Z”, “trace_id”: “47644c95-3bd8-46c3-b320-23fbe9432c00”, “correlation_id”: “5e83afde-3791-4d87-bce2-dfe5dc5d4ee6” } I see you did not mention about certificates, Am I missing something? Thanks!

MARCIO FELIPE LAUBSTEIN
Guest
MARCIO FELIPE LAUBSTEIN

My downstream api is configured with saml sso, i do not know if that could be the issue.

Nikhil
Guest
Nikhil

Hi, We are making an application using Azure Bot Service. Bot service internally calls one of our Web Service to get data based on query. We can consider Bot service as service1 and our Web Service as service2. After we get token from service1 we use that token as assertion to get bearer token from service2 by providing all required input parameters. We are getting error “AADSTS50013: Assertion failed signature validation. [Reason – The provided signature value did not match the expected signature value., Thumbprint of key used by client:…” and we cannot move forward. Can you please suggest what… Read more »