简体   繁体   中英

Azure Ad B2C - Retrieve multiple bearer token for multiple Web Apis in a ASP .net MVC application

We have 2 Web Api that we need to invoke from our applications. Both are configure in Azure AD B2C . Here's 2 scope we need to use to call their endpoints:

We currently have two applications.

  1. A SPA application ( https://github.com/Azure-Samples/active-directory-b2c-javascript-msal-singlepageapp )
  2. An old Asp .net mvc application ( https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi )

The SPA application (using Msal 1 or Msal 2) is able to retrieve the bearer token without any issue for both applications. Using fiddler, we are able to see that our application calls the "/oauth2/v2.0/authorize" endpoint each time it needs a bearer token to call a specific web api. For each call, the "scope" query string parameter is different depending on the api endpoint i need to call. I also wonder where the "state" query string parameter is coming from since it's different for every call.

Anyway, the SPA application is working flawless. Great, the problem is with the old Asp .net mvc web application. You can find a sample provide by Microsoft on this web site: https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi

My understanding is that, you cannot add the two scopes I provided at the top of the case inside the scope property of "app.UseOpenIdConnectAuthentication" object define in the "Startup" class.If you do that, well, B2C will complain and crash.

So, I will only use the first scope for now. In the "TasksController", the "Index" method show how to retrieve a bearer token for the first scope I define here. Once again, it works perfectly. But, let's say I want to fetch a bearer token for my second web api. Just below the original, let' say I use this code to retrieve my second bearer token:

            var scope2 = new string[] { "https://merrychristmast.onmicrosoft.com/MySecondFavoriteApp" };
            var claimsPrincipal = ClaimsPrincipal.Current;
            var objIdclaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);

            string signedInUserID = objIdclaim.Value;

            IConfidentialClientApplication clientapp = ConfidentialClientApplicationBuilder.Create(Globals.ClientId)
                  .WithClientSecret(Globals.ClientSecret)
                  .WithRedirectUri(Globals.RedirectUri)
                  .WithB2CAuthority(Globals.B2CAuthority)
                  .Build();
            new MSALPerUserMemoryTokenCache(clientapp.UserTokenCache, ClaimsPrincipal.Current);

            var accounts2 = await cca.GetAccountsAsync();
            AuthenticationResult result2 = await clientapp.AcquireTokenSilent(scope2, accounts.FirstOrDefault()).ExecuteAsync();

In the result2 variable, the access_token is null. In fiddler, I can see Msal is trying to use the refresh token found in the Msal cache to retrieve the second web api scope. But the response from the server contains the scope of the "MyLovellyApi1" scope. And the access_token is null (Not return from the server). The grant_type use is "grant_type=refresh_token".

On multiple web site, people are saying I should be able to use the refresh token to retrieve additional scope. Does it mean I can only retrieve additional scope if they are members of the "MyLovellyApi1" scope ex: https://merrychristmast.onmicrosoft.com/MyLovellyApi1\read and https://merrychristmast.onmicrosoft.com/MyLovellyApi1/write ?

If that is the case, I think i need to understand how the Spa application using MSAL 1.0 (implicit flow) is able to retrieve multiple bearer token for each of my web api using the "/authorize" endpoint.

Can anyone explain how I can actually do that? I don't understand how I can invoke the "/oauth2/v2.0/authorize" endpoint from my mvc asp.net application and provided all the parameters required to successfully request an access token for my logged user. Every of my attend to do something like failed.

Regards,

The SPA application is based on implicit flow . You could request /authorize endpoint to get access token directly.

ps: the description of state

在此处输入图像描述

The Asp .net mvc application is based on authorization code flow . You need to request /authorize endpoint to get an authorization code first, then send a POST request to the /token endpoint for access token.

Note : Authorization codes MUST be short lived and single-use. If the authorization server observes multiple attempts to exchange an authorization code for an access token, the authorization server SHOULD attempt to revoke all access tokens already granted based on the compromised authorization code.

So you could call to obtain an access token with a new authorization code. Trying to test in Postman will help you understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM