ASP.NET Core API:身份验证弹出窗口未显示在 Swagger UI 中

Dar*_*ara 8 swagger asp.net-core swashbuckle.aspnetcore

我有一个 ASP.NET Core Web API,其中使用 Swashbuckle 集成了 Swagger。我已经使用操作过滤器成功在 Swagger UI 上集成了授权,因为我不想显示匿名 API 的挂锁。

.OperationFilter<AuthorizeFilter>()
Run Code Online (Sandbox Code Playgroud)

在过滤器内,我已经注册了 Swagger UI 的基本身份验证安全要求。

我的问题是,即使在 Swagger UI 上的 API 中进行身份验证,我也不再看到单击挂锁图标时提供的漂亮的身份验证弹出窗口。

有人可以回答,为什么我现在看不到身份验证弹出窗口吗?

abd*_*sco 13

更新 2023-04-17Http根据@mimmoz81的建议更新了安全定义类型


假设您有一些受属性保护的端点[Authorize](也可以放在控制器上)。

[Route("")]
public class HelloController : ControllerBase
{
    [Authorize]
    [HttpGet("secure")]
    public IActionResult GetSomethingPrivate()
    {
        return Ok("secret");
    }

    [HttpGet("public")]
    public IActionResult GetSomethingPublic()
    {
        return Ok("hey");
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要定义适合您需求的安全方案。但不要全局要求它,而是将其添加到操作过滤器中。这里我添加了一个简单的令牌身份验证:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiPlayground", Version = "v1" });
        c.AddSecurityDefinition("token", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.Http,
            In = ParameterLocation.Header,
            Name = HeaderNames.Authorization,
            Scheme = "Bearer"
        });
        // dont add global security requirement
        // c.AddSecurityRequirement(/*...*/);
        c.OperationFilter<SecureEndpointAuthRequirementFilter>();
    });
}
Run Code Online (Sandbox Code Playgroud)

这是引用token我们刚刚创建的身份验证方案的操作过滤器。它检查端点是否需要身份验证,然后添加要求。

internal class SecureEndpointAuthRequirementFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (!context.ApiDescription
            .ActionDescriptor
            .EndpointMetadata
            .OfType<AuthorizeAttribute>()
            .Any())
        {
            return;
        }

        operation.Security = new List<OpenApiSecurityRequirement>
        {
            new OpenApiSecurityRequirement
            {
                [new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "token" }
                }] = new List<string>()
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

当您运行该应用程序时,它会按您的预期工作:

招摇用户界面

身份验证弹出窗口也是如此:

授权弹出窗口

奖励:使用基本身份验证

使用以下值定义新的安全方案:

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddSwaggerGen(c =>
    {
        // ...
        // basic auth scheme (username + password)
        c.AddSecurityDefinition("basic", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.Http,
            Scheme = "basic"
        });
        // dont add global security requirement
        // c.AddSecurityRequirement(/*...*/);
        c.OperationFilter<SecureEndpointAuthRequirementFilter>();
    });
}
Run Code Online (Sandbox Code Playgroud)

然后更新操作过滤器以引用basic身份验证方案:

internal class SecureEndpointAuthRequirementFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (!context.ApiDescription
            .ActionDescriptor
            .EndpointMetadata
            .OfType<AuthorizeAttribute>()
            .Any())
        {
            return;
        }

        operation.Security = new List<OpenApiSecurityRequirement>
        {
            new OpenApiSecurityRequirement
            {
                [new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme, 
                        Id = "basic" // <-- changed "token" -> "basic"
                    }
                }] = new List<string>()
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

身份验证弹出窗口如下所示:

基本身份验证弹出窗口

登录后,请求包含正确的Authorization标头。

标头


Saf*_*oob 5

就我而言,我将JWT 令牌身份验证.NET Core API结合使用。我使用以下代码使用授权令牌配置招摇。该代码将添加全局安全要求。

在启动类的ConfigureServices方法中。

        //Swagger Configuration

        services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
            {
                Title = "API",
                Version = "v2",
                Description = "Your Api Description"
            });
            options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "JWT Authorization header using the Bearer scheme (Example: 'Bearer 12345abcdef')",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "Bearer"
            });
            options.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    },
                    Array.Empty<string>()
                }
            });
        });
Run Code Online (Sandbox Code Playgroud)

并在配置方法中

        app.UseSwagger();

        app.UseSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
        });
Run Code Online (Sandbox Code Playgroud)

运行API项目后,右侧会出现授权按钮。点击授权按钮,授权弹出窗口打开,然后在文本框中使用“承载令牌”传递令牌。

授权对我来说效果很好。