Правильная конфигурация swashbuckle для IdentityServer4 ClientCredentials в ядре 3.1 visual Studio 2019

#swagger #identityserver4 #swashbuckle #.net-core-3.1 #clientcredential

#swagger #identityserver4 #swashbuckle #.net-core-3.1 #клиентский кредит

Вопрос:

У меня есть API, который мне нужно авторизовать (используя атрибут [Authorize]). Сервер идентификации 4 настроен с использованием сгенерированной базы данных, включая таблицы Клиенты, Область видимости, ClientScope, Секреты клиента.

У меня есть внутренний клиент с секретным InternalClientSecret, который отлично работает при авторизации из кода.

Но я не могу понять, как настроить right swashbuckle для make 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);
        }
    }
}
 

Что я делаю не так, есть идеи? Или, может быть, у кого-нибудь есть рабочий пример?