0
votes

I have a ASP.NET Core WebApplication (REST API) that uses AzureB2C for Authentication. This is the Startup.cs

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
                .AddAzureADB2CBearer(options =>
                {
                    options.Instance = "https://tenant.b2clogin.com/tfp/";
                    options.ClientId = "...";
                    options.Domain = "tenant.onmicrosoft.com";
                    options.SignUpSignInPolicyId = "B2C_1A_signup_signin";
                });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }

To support Authentication in Automated Tests, I did try to use client credential Flow, but found out that it is not supported in AzureB2C. Next I came across ROPC Flow which is suggested as alternative (ex: here). But I cannot get it to work.

If I receive a Token using the ROPC Flow.

            dynamic result = await $"https://{tenantName}.b2clogin.com"
                .AppendPathSegment($"{tenantName}.onmicrosoft.com")
                .AppendPathSegment("B2C_1_ROPC_Auth")
                .AppendPathSegment("oauth2/v2.0/token")
                .SetQueryParams(new
                    {
                        client_id,
                        scope = $"6d1aa76b-10fb-47bb-bbec-5d7f7a4e08c4 openid offline_access",
                        username,
                        password,
                        grant_type = "password",
                        repsonse_type = "token id_token"
                    }
                )
                .PostAsync(new StringContent(""))
                .ReceiveJson();

The token looks good and Valid. But If I try to use it to Authenticate my calls to the REST Api, I Receive the following Error:

WWW-Authenticate Bearer error="invalid_token", error_description="The signature key was not found"

After some investigation it looks like the RestAPI is trying to validate the KID using the well-known configuration of my B2C_1A_signup_signin policy. Which makes sense, as It is part of the Options of AddAzureADB2CBearer. If I do change the Policy to B2C_1_ROPC_Auth the token is accepted.

But I do need both Tokens to work, the ones that get created using the B2C_1A_signup_signin Flow and the ROPC flow tokens.

How can I configure my app to accept both configurations?

1

1 Answers

0
votes

If this API is only accessed via a headless authentication, then protect it using Azure AD Client Credentials. Your Azure AD B2C contains an Azure AD inside it. Follow the instructions here: https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-daemon-overview