No auth header sent by swagger UI using Swashbuckle with OAuth code flow in .NET 6

Viewed 453

I am trying to get OAuth code flow with PCKE to work with Swashbuckle (6.2.3) and swagger ui in .NET 6. There are a few things that happen successfully:

  • In swagger UI I can click on "Authorize" button and get redirected to Azure for login.
  • The redirect successfully returns to swagger ui and I can see in the network tab that the token is retrieved from Azure by swagger ui.

The problem is when I try to call the sample weather forecast API using swagger UI, no token is attached to the authorization header and it looks like this in the request:

authorization: Bearer undefined

And here is my code:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C"));

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    
    const string oAuth2 = "oauth2";
    options.AddSecurityDefinition(oAuth2, new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Flows = new OpenApiOAuthFlows
        {
            AuthorizationCode = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new Uri(builder.Configuration["AzureAdB2C:AuthorizationUrl"]),
                TokenUrl = new Uri(builder.Configuration["AzureAdB2C:TokenUrl"]),
                Scopes = {{"openid", "Sign users in"}, {"offline_access", "Maintain access to data you have given it access to"}}
            }
        },
        In = ParameterLocation.Header,
        BearerFormat = "JWT",
        Scheme = "bearer",
        Name = "authorization"
    });
    
    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Id = oAuth2,
                    Type = ReferenceType.SecurityScheme
                },
            }, new List<string> {"openid", "offline_access"}
        }
    });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        options.OAuthClientId(builder.Configuration["AzureAdB2C:ClientId"]);
        options.OAuthScopes("openid", "offline_access");
        options.OAuthUsePkce();
    });
}

app.UseHttpsRedirection();

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

app.MapControllers();

app.Run();

I'm not sure what I'm missing. Any ideas?

UPDATE: I have been able to get it to work with something like this:

        options.UseRequestInterceptor("(req) => { req.headers['Authorization'] = 'Bearer ' + window?.swaggerUIRedirectOauth2?.auth?.token?.id_token; return req; }");

But it doesn't look like a proper solution.

0 Answers
Related