blazorazure-ad-b2cblazor-webassembly

Getting access token in Blazor WASM Standalone


I have a Blazor WASM standalone app that uses Azure AD B2C for user and token management.

I've seen other questions/answers about this issue but in my case none of those approaches have worked and my Blazor WASM Standalone app is NOT able to get access tokens.

My Blazor app is set up as a SPA app on Azure AD B2C and it's important to note that "Access Tokens" and "Id Tokens" options are unchecked under "Implicit grant and hybrid flows" section. Also, "Allow public flows" is set to "No" -- see below. For these settings, I just followed the instructions here: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-azure-active-directory-b2c?view=aspnetcore-8.0#register-an-app-in-azure

enter image description here

I also added the "Read" and "Write" scopes for my API under "Configured Permissions" for my Blazor WASM app -- see below:

enter image description here

On the Blazor WASM side, this is what my Program.cs looks like:

...
builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
    options.ProviderOptions.LoginMode = "redirect";
    //options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    //options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("https://mytenant.onmicrosoft.com/api/MyApiUser.Write");
});

// Add HttpClient for My API calls
builder.Services.AddHttpClient("MyApiClient",
        client => client.BaseAddress = new Uri("https://api.test.com"))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient("MyApiClient"));

Please notice that I commented out the scopes for openid and offline_access but I did try it with them as well. Either way, it doesn't work and no access_token is received.

In this SO question/answer, the developer suggests using the Application Id for the Blazor WASM app instead of the scope URI worked for him. I did try the following and that did NOT work either. Here's that question: Blazor Standalone WASM Unable to get Access Token with MSAL

options.ProviderOptions.DefaultAccessTokenScopes.Add("cb3574c0-305e-4e44-a3b7-ac5f045f94e7"); // options.ProviderOptions.DefaultAccessTokenScopes.Add("https://mytenant.onmicrosoft.com/api/MyApiUser.Write");

Here the GUID value of cb3574c0-305e-4e44-a3b7-ac5f045f94e7 is the Application Id for my Blazor WASM app as assigned by Azure AD B2C.

When I inspect the HttpClient where I make my API calls, I see that DefaultRequestHeaders is null.

I don't believe Azure AD B2C is actually sending an access_token at all. Any idea what I'm doing wrong here?


Solution

  • Note that: Generating access token in Azure AD B2C depends on the scope you pass.

    The error occurred as you are passing wrong scope https://mytenant.onmicrosoft.com/api/MyApiUser.Write

    To resolve the error, make sure to pass scope as var scopes = new[] { "openid", "profile", "offline_access" "https://mytenant.onmicrosoft.com/ClientID/ScopeName" };

    Modify the code by passing the valid scope:

    ...
    builder.Services.AddMsalAuthentication(options =>
    {
        builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
        options.ProviderOptions.LoginMode = "redirect";
        //options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
        //options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
        options.ProviderOptions.DefaultAccessTokenScopes.Add("openid", "profile", "offline_access" "https://mytenant.onmicrosoft.com/ClientID/ScopeName"");
    });
    
    // Add HttpClient for My API calls
    builder.Services.AddHttpClient("MyApiClient",
            client => client.BaseAddress = new Uri("https://api.test.com"))
        .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    
    builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
        .CreateClient("MyApiClient"))
    

    The error "The provided application is not configured to allow public clients." usually occurs if the Azure AD B2C application is not set as public.

    To resolve the error, make sure to set Allow public client flows as YES:

    enter image description here

    Also make sure to configure redirect URL as SPA.

    Reference:

    c# - Null AccessToken returned from AuthenticationResult - Stack Overflow by me