1

我有一个 API,我需要授权(使用属性 [Authorize])身份服务器 4 使用生成的 DB 配置,包括表 Clients、Scope、ClientScope、Client Secrets。

我有带有秘密 InternalClientSecret 的客户端 InternalClient,如果从代码授权,它可以完美运行。

但我不知道如何配置正确的 swashbuckle 以使 swagger 发出授权请求

在此处输入图像描述

在此处输入图像描述

按下授权按钮后:
在此处输入图像描述

API列表也改变了外观:
在此处输入图像描述

如果我到达 API,我会得到 401,如果我按下锁定按钮,我会看到:
在此处输入图像描述

后面的代码:

services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1.0", new OpenApiInfo { Title = "Main API v1.0", Version = "v1.0" });

            if(configuration != null)
            {
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.OAuth2,
                    Flows = new OpenApiOAuthFlows()
                    {
                        ClientCredentials = new OpenApiOAuthFlow()
                        {
                            TokenUrl = new Uri("https://localhost:44339/connect/token"),
                            Scopes = new Dictionary<string, string>()
                            {
                                { "LookupsApi", "LookupsApi" }
                            }
                        }
                    },
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Name = "Bearer",
                            Scheme = "oauth2",
                            Type = SecuritySchemeType.OAuth2,
                            In = ParameterLocation.Header,
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new List<string>()
                    }
                });

            }

            c.OperationFilter<AuthorizeCheckOperationFilter>();
        });

        return services;
    }

    public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
    {
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "Versioned API v1.0");
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "Our Awesome API V1");
            c.OAuthClientId("InternalClient");
            c.OAuthClientSecret("InternalClientSecret");
        });

        return app;
    }
internal class AuthorizeCheckOperationFilter : Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var hasAuthorize = context.ApiDescription.CustomAttributes().OfType<AuthorizeAttribute>().Any();

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

            operation.Security ??= new List<OpenApiSecurityRequirement>(); //new List<IDictionary<string, IEnumerable<string>>>();
            var openApiSecurityRequirement = new OpenApiSecurityRequirement();
            openApiSecurityRequirement.Add(new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2 }, new List<string> {
                    "LookupsApi"
                });
            operation.Security.Add(openApiSecurityRequirement);
        }
    }
}

我做错了什么,有什么想法吗?或者也许有人有一个可行的例子?

4

0 回答 0