Dan Cook
Dan Cook

Reputation: 2072

Swagger not able to authenticate to Azure AD B2C

I have a Web API with a Swagger and an Azure AD B2C tenant.

A React app is able to obtain a token from B2C like:

          msalInstance.loginRedirect({
            scopes: ["openid", "offline_access", process.env.MY_CLIENT_ID],
          });

However the Swagger Authorize function returns AADB2C90205, This+application+does+not+have+sufficient+permissions+against+this+web+resource+to+perform+the+operation

The AddSwagger code in Startup.cs is:

        private void AddSwagger(IServiceCollection services)
        {
            var azureAdB2C = new AzureAdB2CSettings();
            this.Configuration.Bind("AzureAdB2C", azureAdB2C);
            var authUrl = $"https://{azureAdB2C.TenantName}.b2clogin.com/{azureAdB2C.TenantName}.onmicrosoft.com/{azureAdB2C.SignUpSignInPolicyId}/oauth2/v2.0";

            services.AddOpenApiDocument(
                document =>
                    {
                        document.AddSecurity(
                            "bearer",
                            Enumerable.Empty<string>(),
                            new OpenApiSecurityScheme
                                {
                                    Type = OpenApiSecuritySchemeType.OAuth2,
                                    Description = "Azure AAD Authentication",
                                    
                                    Flow = OpenApiOAuth2Flow.Implicit,
                                    Flows = new OpenApiOAuthFlows()
                                                {
                                                    Implicit = new OpenApiOAuthFlow()
                                                                   {
                                                                       Scopes = new Dictionary<string, string>
                                                                                    {
                                                                                        {
                                                                                            $"{azureAdB2C.Instance}/{azureAdB2C.ClientId}/user_impersonation",
                                                                                            "Access Application"
                                                                                        },
                                                                                        {
                                                                                            $"{azureAdB2C.Instance}/{azureAdB2C.ClientId}/access_as_user",
                                                                                            "Access as User"
                                                                                        },
                                                                                    },
                                                                       AuthorizationUrl = $"{authUrl}/authorize",
                                                                       TokenUrl = $"{authUrl}/token",
                                                    },
                                                },
                                });

                        document.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("bearer"));
                    });
        }

The B2C configuration is as follows:

enter image description here

enter image description here

Am I missing anything obvious here?

Upvotes: 3

Views: 6037

Answers (1)

Jim Xu
Jim Xu

Reputation: 23141

If you want to call web api projected by Azure AD B2C, please refer to the folloiwng steps

a. Register web api application in Azure AD B2C enter image description here

b. Define scope

c. Register SPA application in Azure AD B2C enter image description here

enter image description here

d. Grant Permissions.

e. application

  1. package
Microsoft.AspNetCore.Authentication.AzureADB2C.UI
NSwag.AspNetCore
  1. appsettings.json
{
  "AzureAdB2C": {
    "Instance": "https://<>.b2clogin.com/tfp/",
    "ClientId": "<web api clinet id>",
    "Domain": "<>.onmicrosoft.com",
    "SignUpSignInPolicyId": "B2C_1_test"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

public void ConfigureServices(IServiceCollection services)
{
    // snip
      services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme)
                .AddAzureADB2CBearer(options => Configuration.Bind("AzureAdB2C", options));

    // Add security definition and scopes to document
    services.AddOpenApiDocument(document =>
    {
        document.AddSecurity("bearer", Enumerable.Empty<string>(), new OpenApiSecurityScheme
        {
            Type = OpenApiSecuritySchemeType.OAuth2,
            Description = "B2C authentication",
            Flow = OpenApiOAuth2Flow.Implicit,
            Flows = new OpenApiOAuthFlows()
            {
                Implicit = new OpenApiOAuthFlow()
                {
                    Scopes = new Dictionary<string, string>
                        {
                            { "https://<b2c_tenant_name>.onmicrosoft.com/your-api/user_impersonation", "Access the api as the signed-in user" },
                            { "https://<b2c_tenant_name>.onmicrosoft.com/your-api/read", "Read access to the API"},
                            { "https://<b2c_tenant_name>.onmicrosoft.com/your-api/mystery_scope", "Let's find out together!"}
                        },
                    AuthorizationUrl = "https://<b2c_tenant_name>.b2clogin.com/<b2c_tenant_name>.onmicrosoft.com/oauth2/v2.0/authorize?p=<policy_name>",
                    TokenUrl = "https://<b2c_tenant_name>.b2clogin.com/<b2c_tenant_name>.onmicrosoft.com/oauth2/v2.0/token?p=<policy_name>"
                },
            }
        });

        document.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("bearer"));
    });

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

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseOpenApi();
            app.UseSwaggerUi3(settings =>
            {
                settings.OAuth2Client = new OAuth2ClientSettings
                {
                    ClientId = "<spa client id>",
                    AppName = "swagger-ui-client"
                };
            });

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

f.test enter image description here enter image description here

For more details, please refer to the blog.

Upvotes: 8

Related Questions