1
votes

We have a web application which needs authenticated access to several Web APIs. We are using Azure AD B2C for authentication.

I understand you can not include scopes for both resources in one call.

I understand that MSAL is meant to use a refresh token that was cached from the first resource token, to request an access token for the second resource.

IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync();
AuthenticationResult result = await cca.AcquireTokenSilent(scopeForApi2, accounts.FirstOrDefault())

When this call is made, the call doesnt not fail, but the Access Token is null.

Within Azure B2C, the web app, and webapis are registered - and the web app has been granted permission and admin consent to all the scopes from the webapis.

Is this supported using Azure AD B2C and/or MSAL.NET?

We get the first access token for the first resource api successfully:

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        // Generate the metadata address using the tenant and policy information
        MetadataAddress = String.Format(Globals.WellKnownMetadata, Globals.Tenant, Globals.DefaultPolicy),

        // These are standard OpenID Connect parameters, with values pulled from web.config
        ClientId = Globals.ClientId,
        RedirectUri = Globals.RedirectUri,
        PostLogoutRedirectUri = Globals.RedirectUri,

        // Specify the callbacks for each type of notifications
        Notifications = new OpenIdConnectAuthenticationNotifications
        {
            RedirectToIdentityProvider = OnRedirectToIdentityProvider,
            AuthorizationCodeReceived = OnAuthorizationCodeReceived,
            AuthenticationFailed = OnAuthenticationFailed,
        },

        // Specify the claim type that specifies the Name property.
        TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name",
            ValidateIssuer = false
        },

        // Specify the scope by appending all of the scopes requested into one string (separated by a blank space)
        Scope = $"openid profile offline_access {Globals.ReadTasksScopeApi1} {Globals.WriteTasksScopeApi1}"
    }
);

we get the first access token using the authorizationcode - we receive an access token and refresh token

IConfidentialClientApplication confidentialClient 
     = MsalAppBuilder.BuildConfidentialClientApplication(
        new ClaimsPrincipal(notification.AuthenticationTicket.Identity));

// Upon successful sign in, get & cache a token using MSAL
AuthenticationResult result = await confidentialClient
    .AcquireTokenByAuthorizationCode(Globals.Scopes_Api1, notification.Code)
    .ExecuteAsync();

I have also tried adding the "resource" query parameter but it doesnt seem to make any difference:

var scope = new string[] { Globals.ReadTasksScopeApi2 };


IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync();
AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault())
.WithExtraQueryParameters(new Dictionary<string, string>
{
   // { "resource", "https://myb2c.onmicrosoft.com/api2" },    // tried appid and guid
    { "resource", "0a6ab6b5-1b88-49fe-a6cf-19f1878d3508" }
})
.ExecuteAsync();

Why is the Access Token null for the second call to AcquireTokenSilent on a second resource using Azure AD B2C?

1
What is the scope name you pass in? scopeForApi2Jas Suri - MSFT
We have two api with the following ApplicationID uri: myb2c.onmicrosoft.com/api and myb2c.onmicrosoft.com/api2 . The first api has scopes as follows: myb2c.onmicrosoft.com/api/demo.write myb2c.onmicrosoft.com/api/demo.read . And the second api has myb2c.onmicrosoft.com/api2/demo.write myb2c.onmicrosoft.com/api2/demo.read. In the scopeForApi2 variable we are asking for myb2c.onmicrosoft.com/api2/demo.readsolidstore
This does work with a standard AzureAD directory, but not for Azure AD B2C.solidstore
I can reproduce this issue, will do some further research.Tony Ju
Is BuildConfidentialClientApplication using WithB2CAuthority()?TiagoBrenck

1 Answers

1
votes

2/19/2020

I have confirmed with Azure support engineer that Azure AD B2C doesn't support such scenario.