{"id":5801,"date":"2019-08-04T03:03:11","date_gmt":"2019-08-04T03:03:11","guid":{"rendered":"https:\/\/blogs.aaddevsup.xyz\/?p=5801"},"modified":"2020-08-07T18:29:13","modified_gmt":"2020-08-07T18:29:13","slug":"understanding-azure-ads-on-behalf-of-flow-aka-obo-flow","status":"publish","type":"post","link":"https:\/\/blogs.aaddevsup.xyz\/2019\/08\/understanding-azure-ads-on-behalf-of-flow-aka-obo-flow\/","title":{"rendered":"Understanding Azure AD\u2019s On-Behalf-Of flow (aka OBO flow)"},"content":{"rendered":"
Microsoft Azure Active Directory supports an OAuth2 protocol extension<\/a> called On-Behalf-Of flow (OBO flow). This is documented at both the Microsoft Identity Platform V1<\/a> and V2<\/a> endpoint. The OBO flow is used in the following scenario. Both Web API 1 and Web API 2 are protected by Azure AD.<\/p>\n <\/p>\n Let’s look at the parameters used in an OBO flow at the V1 endpoint below. I want to call out a few highlighted<\/span> parameters as their significance will become more obvious a little bit later.<\/p>\n assertion:<\/strong> client_id:<\/strong> Resource:<\/strong> <\/p>\n Let’s look at an OBO end to end traffic in Fiddler<\/a>:<\/p>\n Frame 1 \u2013 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<\/p>\n Hover over image to enlarge<\/em><\/span><\/p>\n 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.<\/p>\n Hover over image to enlarge<\/span><\/em><\/p>\n It is extremely important to use the correct parameter in the OBO flow. Note that the OBO parameters client_id <\/strong><\/span>and the assertion<\/strong><\/span> (access token) are for the calling application (Web API 1) in this token exchange request.<\/p>\n I have seen a few AADSTS error returned for this flow when either the client_id <\/strong><\/span>or the assertion<\/strong><\/span> parameters used are not for the calling application (Web API 1). Below are a few examples:<\/p>\n 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 \u2026<\/strong><\/span><\/p>\n 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:\u2026<\/strong><\/span><\/p>\n Root cause: The access token used in the assertion is for Microsoft Graph resource (https:\/\/graph.microsoft.com<\/a>) HTTP 400 error: AADSTS50013: Assertion failed signature validation. [Reason – The key was not found., Thumbprint of key used by client: ‘B25930C…..<\/span><\/strong> HTTP 500 error: AADSTS50000: There was an error issuing a token.<\/strong><\/span><\/p>\n Root cause: the client id used is either not valid or does not exist in the tenant. <\/li>\n<\/ul>\n 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<\/a> for more info). The key is in the parameter requested_token_type<\/strong>. The allowed values are<\/p>\n urn:ietf:params:oauth:token-type:saml2 <\/strong>\u2013 SAML 2.0 token urn:ietf:params:oauth:token-type:saml1 <\/strong>\u2013 SAML 1.1 token Note:<\/strong> <\/p>\n Note<\/strong>: Azure AD returns the SAML token encoded in UTF8 and Base64URL as noted in the documentation<\/a><\/p>\n\n
\n<\/span>this is the access token issued in step 2 above<\/p>\n
\n<\/span>application id of Web API 1<\/p>\n
\n<\/span>this is Application ID URI or Application ID of Web API 2<\/p>\nCommon pitfall customers run into when using the OBO flow<\/h1>\n
\n<\/em><\/span><\/p>\n
\n<\/em><\/span><\/p>\n
\nRoot 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)<\/span>.<\/em><\/span><\/p>\n
\n<\/em><\/span><\/p>\nHow can I diagnose this issue?<\/h1>\n
\n
What if my Web API 2 is SAML Application?<\/h1>\n
\n<\/strong><\/span><\/p>\n
\n<\/span><\/p>\n
\nAt the time of this writing, this JWT \u2013 SAML token exchange OBO flow is only available in the V1 endpoint.<\/span><\/span>
\n<\/span><\/p>\nWhat about Azure AD B2C?<\/h1>\n