Search code examples
c#asp.net-coreasp.net-core-webapiswagger-ui

Asp.net core Web API for SPA - How to implement Swagger Authentication without having to obtain the Access token outside of the Web API and pass it?


We are building a SPA with React & ASP.Net core Web API.

React would pass the Auth_Token to ASP.Net core Web API to authenticate, this works.

As App Registration is done for the front-end application along with Scope & Roles, I am not sure how to implement Authentication for Swagger in ASP.Net core Web API.

At present, I have the following swagger configuration

    private void AddSwagger(IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "Track Management API",
            });

            var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile);

            c.IncludeXmlComments(xmlCommentsFullPath);

            var jwtSecurityScheme = new OpenApiSecurityScheme
            {
                Scheme = "bearer",
                BearerFormat = "JWT",
                Name = "JWT Authentication",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.Http,
                Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",

                Reference = new OpenApiReference
                {
                    Id = JwtBearerDefaults.AuthenticationScheme,
                    Type = ReferenceType.SecurityScheme
                }
            };

            c.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);

            c.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                { jwtSecurityScheme, Array.Empty<string>() }
            });
        });
    }

Currently, we must get the Auth_Token outside of the ASP.Net core Web API and pass it to it.

enter image description here

Can Developers generate the required Auth_Token directly from the Swagger page to simplify this process?

Update: The below Swagger configuration try to get the required auth_code however it uses the Web API URL as the redirection URL and fails. What I want is that it should use the Front-end URL as the redirection URL to generate the auth_code but pass it to the Web API?

            c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
            {
                Description = "OAuth2.0 Auth Code with PKCE",
                Name = "oauth2",
                Type = SecuritySchemeType.OAuth2,
                Flows = new OpenApiOAuthFlows
                {
                    AuthorizationCode = new OpenApiOAuthFlow
                    {
                        AuthorizationUrl = new Uri($"https://login.microsoftonline.com/{this.Configuration.GetValue<string>("AzureAd:TenantId")}/oauth2/authorize"),
                        TokenUrl = new Uri($"https://login.microsoftonline.com/{this.Configuration.GetValue<string>("AzureAd:TenantId")}/v2.0/token"),
                        Scopes = new Dictionary<string, string>
                        {
                            { this.Configuration.GetValue<string>("AzureAd:ApiScope"), "Allows Read and Write" }
                        }
                    }
                }
            });
            c.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
                    },
                    new[] { this.Configuration.GetValue<string>("AzureAd:ApiScope") }
                }
            }); 

The Other option that I see is to add the Web API URL as the redirect URL in the app registration for the lower environment.


Solution

  • This worked for me in combination with Azure AD B2C:

    config.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Scheme = "oauth2",
        OpenIdConnectUrl = new Uri(builder.Configuration["AzureAd:Authority"]),
        Flows = new OpenApiOAuthFlows
        {
            Implicit = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new Uri(builder.Configuration["AzureAd:Authority"], UriKind.Absolute),
                Scopes = new Dictionary<string, string>
                    {
                        { builder.Configuration["AzureAd:Scopes"], "Access web API" },
                    }
            }
        }
    });
    
    config.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
                },
                new[] { builder.Configuration["AzureAd:Scopes"] }
            }
        });