Search code examples
authenticationazure-active-directoryaccess-tokenazure-ad-b2c

Multiple access tokens with Azure AD B2C


We have a web application which needs authenticated access to several Web APIs. We are using Azure AD B2C for authentication, which we have working okay except for one very frustrating and very limiting issue: we can only ever get back one valid access token at a time, yet we need several.

The snippet below shows the area of concern.

private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
{
    await GetAccessToken(notification, TaskScopes);
    await GetAccessToken(notification, UserScopes);
}

private async Task<AuthenticationResult> GetAccessToken(AuthorizationCodeReceivedNotification notification, string[] scopes)
{
    string signedInUserID = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
    TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
    ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null);
    try
    {
        return await cca.AcquireTokenByAuthorizationCodeAsync(notification.Code, scopes);
    }
    catch (Exception ex)
    {
        //TODO: Handle
        throw;
    }
}

The code snippets shown are called after the authentication token is received from Azure AD B2C. When this code is executed as shown, the first of the two access tokens is returned and is fully valid. However, the second one has access_token: null and the scopes from the first token.

Further, if we simply comment out either of the two calls to GetAccessToken, the remaining call works as expected, no matter which of the two it is. That would seem to indicate that all of our configurations are correct, so I won't post those here for review.

All of the sample code I've seen only ever shows one access token being acquired. And again, when we isolate either of the two calls, it works flawlessly. It only fails if we try to acquire both tokens, and always on the second of the two, no matter the order. Also, we are not encountering any exceptions when this happens.

Can anyone provide any clues as to what may be going on here? Thanks for your help.


Solution

  • The fundamental problem is that by the OAuth standard, you shouldn't attempt to use the same authorization code more than once.

    From https://www.rfc-editor.org/rfc/rfc6749#section-10.5

    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 conmpromnised authorization code.

    So, Azure AD B2C just can't support your use-case at this time since you can't request multiple audiences and scopes in a single access token.

    If you're in control of those several APIs and can make them so that they share a single audience, but maybe have their own scopes, you could use a single access token for them all.