Swashbuckle. NET Основной пользовательский заголовок авторизации не отражается ни в одном запросе API - PullRequest
0 голосов
/ 26 марта 2020

В течение последних нескольких дней я тщательно изучал документацию для реализации поддержки настраиваемых заголовков авторизации для Swashbuckle.AspNetCore 5.xx и не смог распространить SwaggerUI для правильной отправки запросов API из документов API на любые из API (API получают удар, но он всегда терпит неудачу в моем атрибуте Authorize, потому что ключ заголовка, который содержит Ключ API, пуст).

Я также наткнулся на эти вопросы:

  1. SwaggerUI с авторизацией токена канала-носителя .NetCore 3.0
  2. Авторизация для канала-носителя JWT в Swashbuckle. NET Core 2
  3. Как задокументировать аутентификацию ключа API с помощью Swashbuckle.AspNetCore v5.0.0-rc2

Я нахожусь на 5.2.0 на всех пакетах Swashbuckle с. NET Core 3.1.2.

Кажется, не работает! : (

Вот мои ConfigureServices для аутентификации, авторизации и Swagger DI

services.AddAuthentication(options =>
            {
                options.DefaultScheme = ApiKeyAuthenticationOptions.DefaultScheme;
                options.DefaultAuthenticateScheme = ApiKeyAuthenticationOptions.DefaultScheme;
            })
                .AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(
                    ApiKeyAuthenticationOptions.DefaultScheme, o => { });

            services.AddAuthorization(options =>
            {
                var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
                    ApiKeyAuthenticationOptions.DefaultScheme);

                defaultAuthorizationPolicyBuilder = 
                    defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();

                options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
            });

            services.AddSwaggerGen(config =>
            {
                config.SwaggerDoc(GlobalApiVariables.CURRENT_API_VERSION, new OpenApiInfo {
                    Title = "XXXX API", 
                    Version = GlobalApiVariables.CURRENT_API_REVISION.ToString()
                });

                config.EnableAnnotations();

                // Adds "(Auth)" to the summary so that you can see which endpoints have Authorization
                config.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
                // or use the generic method, e.g. c.OperationFilter<AppendAuthorizeToSummaryOperationFilter<MyCustomAttribute>>();

                // [SwaggerRequestExample] & [SwaggerResponseExample]
                // version < 3.0 like this: c.OperationFilter<ExamplesOperationFilter>(); 
                // version 3.0 like this: c.AddSwaggerExamples(services.BuildServiceProvider());
                // version > 4.0 like this:
                config.ExampleFilters();
                config.OperationFilter<AddResponseHeadersFilter>(); // [SwaggerResponseHeader]

                // Locate the XML file being generated by .NET Core
                var filePath = Path.Combine(AppContext.BaseDirectory, 
                    $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
                config.IncludeXmlComments(filePath);

                // Define the Api Key scheme that's in use (i.e. Implicit Flow)
                config.AddSecurityDefinition(ApiKeyAuthenticationOptions.DefaultScheme, new OpenApiSecurityScheme
                {
                    Description = "Testtest",
                    In = ParameterLocation.Header,
                    Name = ApiKeyAuthenticationOptions.HeaderKey,
                    Type = SecuritySchemeType.ApiKey,
                    Flows = new OpenApiOAuthFlows
                    {
                        Implicit = new OpenApiOAuthFlow
                        {
                            AuthorizationUrl = new Uri("/connect/validate", UriKind.Relative),
                            Scopes = new Dictionary<string, string>
                            {
                                { "readAccess", "Access read operations" },
                                { "writeAccess", "Access write operations" }
                            }
                        }
                    }
                });

                // add Security information to each operation for OAuth2
                config.OperationFilter<SecurityRequirementsOperationFilter>();

                config.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme, 
                                Id = ApiKeyAuthenticationOptions.DefaultScheme
                            }
                        },
                        new[] { "readAccess", "writeAccess" }
                    }
                });
            });
            services.AddSwaggerExamplesFromAssemblies(Assembly.GetEntryAssembly());

А также, в Configure я добавил:

app.UseSwagger(c =>
            {
                c.RouteTemplate = "/{documentName}/swagger.json";
            });

            app.UseSwaggerUI(c =>
            {
                c.DocumentTitle = "XXXXX Documentation";
                c.RoutePrefix = "";
                c.SwaggerEndpoint($"/{GlobalApiVariables.CURRENT_API_VERSION}/swagger.json", 
                    $"XXXX v{GlobalApiVariables.CURRENT_API_REVISION}");
                c.OAuthClientSecret(ApiKeyAuthenticationOptions.HeaderKey);
            });

Вот ApiKeyAuthenticationOptions если вам это нужно:

public class ApiKeyAuthenticationOptions : AuthenticationSchemeOptions
    {
        public const string DefaultScheme = "API Key";
        public string Scheme => DefaultScheme;
        public string AuthenticationType = DefaultScheme;
        public const string HeaderKey = "X-Api-Key";
    }

Также вот тест: enter image description here

Дайте мне знать, что я делаю неправильно, чем вы так сильно впереди времени!

...