2

I have three applications participating the AzureAD OBO flow :

  1. Angular FrontEnd --> Registered with AzureAD as OIDC app

  2. ASP.NET Core Web API --> Registered with AzureAD as SAML app

  3. NAV OData Service --> Registered with AzureAD as SAML app

Here goes the complete flow :

  1. Angular frontend application signs a user into Azure AD and request a delegated access token for Web API 1 (ASP.NET Core Web API)

  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 (NAV OData Services) 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 1 uses the new access token to call Web API 2

In the above I am getting error in the Step 3.

Error details :

 One or more errors occurred. (AADSTS50013: Assertion failed signature validation. [Reason - The key was not found., Thumbprint of key used by client: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx']
    Trace ID: afc20e5e-ebea-4546-af4b-820f48083e01
    Correlation ID: b5d8d7b5-52d1-430d-af81-d34918970831
    Timestamp: 2021-05-03 11:35:25Z)

enter image description here

Can anyone help me here by providing their guidance to fix this issue?

In this case Angular Front is using implicit flow.

https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/authorize?response_type=token&scope=api://xxxx--<WEB API 1>.default%20openid%20profile&client_id=<Application (client) ID>&redirect_uri=<ApplicationURL>&state=xxxx&nonce=yyyy&client_info=1&x-client-SKU=MSAL.JS&x-client-Ver=msal&login_hint=mytestaccount@mydomain.com&client-request-id=yyyyyy&prompt=none&response_mode=fragment

Here goes the id_token received :

{
  "aud": "<Application (client) ID>",
  "iss": "https://login.microsoftonline.com/<tenantid>/v2.0",
  "iat": 1620380572,
  "nbf": 1620380572,
  "exp": 1620384472,
  "aio": "AWQAm/8TAAAAIVowa1CNNUEB/tB/OcgatUBo9SzDJch09USynyiE+S+be6xkV9TczjRol4Td0czWrdsrzoqDBHUQxbAcnPT90InTNwLfYeHon5Vvk6eFsn2omrgpYlCj90QIXtIoduhd",
  "email": "mytestaccount@mydomain.com",
  "name": "mytestaccount, mytestaccount",
  "nonce": "078bca2a-35ef-457d-96d8-92db7ac3d106",
  "oid": "96035811-49f6-4246-923f-4edba4555e14",
  "preferred_username": "mytestaccount@mydomain.com",
  "rh": "0.ASYA8UXaNizdH02vE1q-RrmZIYsBYTzBse5Co7kY9CZdWDcmALA.",
  "sub": "BAc2RwnOjKjv8vxtS0zOSQ0kgQ74zEvWJDmWnMoWdyM",
  "tid": "36da45f1-dd2c-4d1f-af13-5abe46b99921",
  "uti": "8r7u-zYcr0GSNUdl4STUAQ",
  "ver": "2.0"
}

Access token for accessing WEB API 1:

{
  "aud": "api://xxxx--<WEB API 1>",
  "iss": "https://sts.windows.net/36da45f1-dd2c-4d1f-af13-5abe46b99921/",
  "iat": 1620380574,
  "nbf": 1620380574,
  "exp": 1620384474,
  "acr": "1",
  "aio": "AVQAq/8TAAAAoi/awR8N8P1eapXNZfcGKhsy9uKyL6qv77raeIKYLOyZjXtsVKXMELCu+qZvKJtSaYm/nemvyUPc2OvJiPrvwpwrteqSU1iYM5C4xfPTxHo=",
  "amr": [
    "pwd",
    "rsa",
    "mfa"
  ],
  "appid": "<Application (client) ID>",
  "appidacr": "0",
  "deviceid": "b55e39a3-f492-4679-83e2-53fcd024beba",
  "email": "mytestaccount@mydomain.com",
  "family_name": "mytestaccount",
  "given_name": "mytestaccount",
  "ipaddr": "xx.xx.xx.xx",
  "name": "mytestaccount, mytestaccount",
  "oid": "96035811-49f6-4246-923f-4edba4555e14",
  "onprem_sid": "S-1-5-21-238447276-1040861923-1850952788-976396",
  "rh": "0.ASYA8UXaNizdH02vE1q-RrmZIYsBYTzBse5Co7kY9CZdWDcmALA.",
  "scp": "user_impersonation",
  "sub": "F5atxEe7z2ooojdNoFhaAG_Xs2SBnnkYKJ4yCCWT1HA",
  "tid": "36da45f1-dd2c-4d1f-af13-5abe46b99921",
  "unique_name": "mytestaccount@mydomain.com",
  "upn": "mytestaccount@mydomain.com",
  "uti": "ll2WpznLGEq23DrUk4eoAQ",
  "ver": "1.0"
}
santosh kumar patro
  • 7,231
  • 22
  • 71
  • 143
  • I think this is the reason for the `scope`. What is the `scope` you set? – Carl Zhao May 07 '21 at 01:46
  • Both the WEB API1 (ASP.NET Core API) and WEB API 2(NAV OData services) are exposed as APIs with the "Expose an API" option present in the Azure portal. At Angular frontend app level under API Permissions , WEB API 1 has been added with Type: Delegated and similarly at WEB API 1 level permission has been added to access WEB API 2 (NAV OData Services) WITH Type: Delegated. Scope details : a. Angular calls the ASP.NET Core API using the scope: api://xxxxxx/user_impersonation, b.ASP.NET Core API initiates the NAV OData Services with the scope: api://yyyyyyy/user_impersonation – santosh kumar patro May 07 '21 at 08:24
  • Parse your api 1 and api 2 access tokens and provide screenshots. – Carl Zhao May 07 '21 at 08:48
  • I have updated the question with the id_token and accesstoken used for WEB API1 – santosh kumar patro May 07 '21 at 11:02

1 Answers1

4

I can get access tokens for api 1 and api 2. This is my test process:

First, I made the api of api 1 expose, and added client application.

enter image description here

Next, use the implicit flow to obtain the access token of the middle layer api 1. Request the id token and access token in the browser.

https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize?
client_id={client_id}
&response_type=id_token token
&redirect_uri={redirect_uri}
&scope=openid api://{api 1 client id}/user_impersonation
&response_mode=fragment
&state=12345
&nonce=678910

Parse the access token of api 1.

enter image description here

Next, expose the api of api 2 and add api 1 as a client application.

enter image description here

Finally, use OBO flow to get the access token of api 2 (note: the assertion parameter is the access token of api 1).

enter image description here

Parse the access token of api 2.

enter image description here

Carl Zhao
  • 8,543
  • 2
  • 11
  • 19
  • Thanks much @CarlZhao for your detailed response. Can you please help me to know in your case API1 is OIDC or SAML based app and the same question applies to API 2 also. As mentioned in my question in my case only Angular Front end is registered as OIDC app and the other API1 and API2 are registered as SAML based apps. Any help on this issue is much appreciated – santosh kumar patro May 10 '21 at 15:09
  • I have setup all the apps as OIDC app now and followed your sample mentioned above. On testing the OBO flow (get the second token) I am getting the error :AADSTS50027: JWT token is invalid or malformed.\r\nTrace ID: c683b4cf-f854-48d1-b9cb-48f4741a6200\r\nCorrelation ID: 89a37162-07e6-4589-a77c-6f23bb2274f9\r\nTimestamp: 2021-05-20 11:45:01Z" – santosh kumar patro May 20 '21 at 13:38
  • I was able to resolve the above issue after proper verification of the Bearertoken from the request details. The solution works fine in case of complete OIDC apps flow – santosh kumar patro May 20 '21 at 18:24
  • @santoshkumarpatro I am very happy to know that the problem has been solved. – Carl Zhao May 28 '21 at 02:40
  • @santoshkumarpatro If my answer is helpful for you, you can accept it as answer( click on the check mark beside the answer to toggle it from greyed out to filled in.) You can also add your own answer and accept it. This can be beneficial to other community members. Thank you. – Carl Zhao May 28 '21 at 02:42
  • Thanks much @CarlZhao for your support on this issue. It was a great learning experience for me :) – santosh kumar patro May 28 '21 at 08:14