在 .NET 6 中使用 Swashbuckle 和 OAuth 代码流,swagger UI 没有发送任何身份验证标头

问题描述 投票:0回答:2

我正在尝试使用 PCKE 获取 OAuth 代码流,以便与 Swashbuckle (6.2.3) 和 .NET 6 中的 swagger ui 一起使用。有一些事情发生了成功:

  • 在 swagger UI 中,我可以单击“授权”按钮并重定向到 Azure 进行登录。
  • 重定向成功返回到 swagger ui,我可以在网络选项卡中看到令牌是通过 swagger ui 从 Azure 检索的。

问题是当我尝试使用 swagger UI 调用示例天气预报 API 时,授权标头中没有附加任何令牌,并且在请求中看起来像这样:

authorization: Bearer undefined

这是我的代码:

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();

我不确定我错过了什么。有什么想法吗?

更新: 我已经能够让它与这样的东西一起工作:

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

但这看起来不是一个合适的解决方案。

swagger swagger-ui openapi swashbuckle
2个回答
0
投票

您可以在 OpenApiSecurityScheme 中指定使用 id_token 而不是默认的 access_token,方法是将其添加到扩展中:

Extensions =
{
  // Setting x-tokenName to id_token will send response_type=token id_token and the nonce to the auth provider.
  // x-tokenName also specifieds the name of the value from the response of the auth provider to use as bearer token.
  { "x-tokenName", new OpenApiString("id_token") }
}

来源:https://github.com/inouiw/SwaggerUIJsonWebToken/blob/master/Program.cs


0
投票

您已经定义了

SecurityDefinition
SecurityRequirement
,但错过了指定哪些端点需要授权的部分。该令牌仅附加到调用授权端点的请求。

您需要添加

options.OperationFilter<MyOperationFilter>();

到您的

AddSwaggerGen(
配置,过滤器如下所示:

public class MyOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any())
        {
            operation.Security = new List<OpenApiSecurityRequirement>
            {
                //same security requirment defined in AddSecurityRequirement
                new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Id = oAuth2,
                                Type = ReferenceType.SecurityScheme
                            },
                        }, new List<string> {"openid", "offline_access"}
                    }
                }
            };
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.