带有 .NetCore 3.0 不记名令牌授权的 SwaggerUI

Vah*_*hiD 6 swagger swagger-ui asp.net-core asp.net-core-webapi .net-core-3.0

我正在尝试将授权标头添加到 SwaggerUI api 测试中。下面是我的 Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
       
        services.AddControllers();
        services.Configure<ApiBehaviorOptions>(options =>
        {
            options.SuppressModelStateInvalidFilter = true;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "API",
                Description = "QPIN API with ASP.NET Core 3.0",
                Contact = new OpenApiContact()
                {
                    Name = "Tafsir Dadeh Zarrin",
                    Url = new Uri("http://www.tdz.co.ir")
                }
            });
            var securitySchema = new OpenApiSecurityScheme
            {
                Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey
            };
            c.AddSecurityDefinition("Bearer", securitySchema);
            
            var securityRequirement = new OpenApiSecurityRequirement();
            securityRequirement.Add(securitySchema, new[] { "Bearer" });
            c.AddSecurityRequirement(securityRequirement);
            
        });
    }

    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
    {
        app.UseCors("Cors");


        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMiddleware<ApiResponseMiddleware>();
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
        app.UseRouting();

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


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

    }
Run Code Online (Sandbox Code Playgroud)

授权按钮已添加到 Swagger UI,我已输入所需的访问令牌,如下所示

授权 swaggerUI

但问题是当我想尝试一个 API 时,令牌没有被添加到 API 请求中,当我点击 API 上的锁定图标时,它显示没有任何可用的授权,见下文

在此处输入图片说明

Tao*_*hou 27

您的代码中有两点:

  1. 对于OpenApiSecurityRequirementin OpenApiSecurityRequirement,需要设置OpenApiReference
  2. 需要指定Schemebearer

这是一个工作演示:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "API",
        Description = "QPIN API with ASP.NET Core 3.0",
        Contact = new OpenApiContact()
        {
            Name = "Tafsir Dadeh Zarrin",
            Url = new Uri("http://www.tdz.co.ir")
        }
    });
    var securitySchema = new OpenApiSecurityScheme
    {
        Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
        }
    };
    c.AddSecurityDefinition("Bearer", securitySchema);

    var securityRequirement = new OpenApiSecurityRequirement();
    securityRequirement.Add(securitySchema, new[] { "Bearer" });
    c.AddSecurityRequirement(securityRequirement);
});
Run Code Online (Sandbox Code Playgroud)


Kir*_*lev 12

我的实现 - 排除非受保护端点上的锁 - 与 OperationFilter

internal static void SwaggerSetup(this IServiceCollection services, OpenApiInfo settings)
    {
        if (settings.Version != null)
        {
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc(settings.Version, settings);
                c.OperationFilter<AddAuthHeaderOperationFilter>();
                c.AddSecurityDefinition("bearer", new OpenApiSecurityScheme
                {
                    Description = "`Token only!!!` - without `Bearer_` prefix",
                    Type = SecuritySchemeType.Http,
                    BearerFormat = "JWT",
                    In = ParameterLocation.Header,
                    Scheme = "bearer"
                });
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

OperationFilter

private class AddAuthHeaderOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var isAuthorized = (context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any()
                                && !context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any()) //this excludes controllers with AllowAnonymous attribute in case base controller has Authorize attribute
                                || (context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any()
                                && !context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any()); // this excludes methods with AllowAnonymous attribute

            if (!isAuthorized) return;

            operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" });
            operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" });

            var jwtbearerScheme = new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearer" }
            };

            operation.Security = new List<OpenApiSecurityRequirement>
            {
                new OpenApiSecurityRequirement { [jwtbearerScheme] = new string []{} }
            };
        }
    }
Run Code Online (Sandbox Code Playgroud)

参考https://thecodebuzz.com/jwt-authorize-swagger-using-ioperationfilter-asp-net-core/

刚刚添加了排除AllowAnonymous装饰方法的条件

结果