Как отправить пользовательские заголовки с запросами в пользовательский интерфейс Swagger?

У меня есть некоторые конечные точки в API - /user/login, /products.

В пользовательском интерфейсе Swagger я отправляю email и password в /user/login, и в качестве ответа я получаю строку token.

Затем я могу скопировать маркер из ответа и хочу использовать его как Authorization значение заголовка в запросах ко всем URL-адресам, если он присутствует, и /products в качестве примера.

Должен ли я вручную вводить текстовый ввод где-то на странице пользовательского интерфейса Swagger, а затем помещать туда токен и каким-то образом вводить в запросы или есть инструменты для более эффективного управления им?

Ответ 1

Вы можете добавить параметр заголовка к вашему запросу, и Swagger-UI покажет его в виде редактируемого текстового поля:

swagger: "2.0"
info:
  version: 1.0.0
  title: TaxBlaster
host: taxblaster.com
basePath: /api
schemes:
- http

paths:

  /taxFilings/{id}:

    get:
      parameters:
      - name: id
        in: path
        description: ID of the requested TaxFiling
        required: true
        type: string
      - name: auth
        in: header
        description: an authorization header
        required: true
        type: string
      responses:
        200:
          description: Successful response, with a representation of the Tax Filing.
          schema:
            $ref: "#/definitions/TaxFilingObject"
        404:
          description: The requested tax filing was not found.

definitions:
  TaxFilingObject:
    type: object
    description: An individual Tax Filing record.
    properties:
      filingID:
        type: string
      year:
        type: string
      period:
        type: integer
      currency:
        type: string
      taxpayer:
        type: object

Swagger-UI with auth param text box

Вы также можете добавить определение безопасности с типом apiKey:

swagger: "2.0"
info:
  version: 1.0.0
  title: TaxBlaster
host: taxblaster.com
basePath: /api
schemes:
- http

securityDefinitions:
  api_key:
    type: apiKey
    name: api_key
    in: header
    description: Requests should pass an api_key header.

security: 
 - api_key: []

paths:

  /taxFilings/{id}:

    get:
      parameters:
      - name: id
        in: path
        description: ID of the requested TaxFiling
        required: true
        type: string

      responses:
        200:
          description: Successful response, with a representation of the Tax Filing.
          schema:
            $ref: "#/definitions/TaxFilingObject"
        404:
          description: The requested tax filing was not found.

definitions:
  TaxFilingObject:
    type: object
    description: An individual Tax Filing record.
    properties:
      filingID:
        type: string
      year:
        type: string
      period:
        type: integer
      currency:
        type: string
      taxpayer:
        type: object

Объект securityDefinitions определяет схемы безопасности.

Объект security (называемый в Swagger-OpenAPI "требованиями безопасности") применяет схему безопасности к заданному контексту. В нашем случае мы применяем его ко всему API, объявляя требование безопасности на высшем уровне. При желании мы можем переопределить его в пределах отдельных элементов пути и/или методов.

Это был бы предпочтительный способ указать вашу схему безопасности; и он заменяет параметр заголовка из первого примера. К сожалению, в Swagger-UI нет текстового поля для управления этим параметром, по крайней мере, в моем тестировании.

Ответ 2

В ASP.net WebApi самым простым способом передачи заголовка в Swagger UI является реализация метода Apply(...) в интерфейсе IOperationFilter.

Добавьте это к вашему проекту:

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
        {
            name = "MyHeaderField",
            @in = "header",
            type = "string",
            description = "My header field",
            required = true
        });
    }
}

В SwaggerConfig.cs зарегистрируйте фильтр сверху, используя c.OperationFilter<>():

public static void Register()
{
    var thisAssembly = typeof(SwaggerConfig).Assembly;

    GlobalConfiguration.Configuration 
        .EnableSwagger(c =>
        {
            c.SingleApiVersion("v1", "YourProjectName");
            c.IgnoreObsoleteActions();
            c.UseFullTypeNameInSchemaIds();
            c.DescribeAllEnumsAsStrings();
            c.IncludeXmlComments(GetXmlCommentsPath());
            c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());


            c.OperationFilter<AddRequiredHeaderParameter>(); // Add this here
        })
        .EnableSwaggerUi(c =>
        {
            c.DocExpansion(DocExpansion.List);
        });
}

Ответ 3

В ASP.NET Core 2 Web API, используя пакет 2.1.0 Swashbuckle.AspNetCore, реализуйте IDocumentFilter:

SwaggerSecurityRequirementsDocumentFilter.cs

using System.Collections.Generic;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace api.infrastructure.filters
{
    public class SwaggerSecurityRequirementsDocumentFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument document, DocumentFilterContext context)
        {
            document.Security = new List<IDictionary<string, IEnumerable<string>>>()
            {
                new Dictionary<string, IEnumerable<string>>()
                {
                    { "Bearer", new string[]{ } },
                    { "Basic", new string[]{ } },
                }
            };
        }
    }
}

В Startup.cs настройте определение безопасности и зарегистрируйте пользовательский фильтр:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(c =>
    {
        // c.SwaggerDoc(.....

        c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
        {
            Description = "Authorization header using the Bearer scheme",
            Name = "Authorization",
            In = "header"
        });

        c.DocumentFilter<SwaggerSecurityRequirementsDocumentFilter>();
    });
}

В интерфейсе Swagger нажмите кнопку "Авторизовать" и установите значение для токена.

Window to set value

Результат:

curl -X GET "http://localhost:5000/api/tenants" -H "accept: text/plain" -H "Authorization: Bearer ABCD123456"

Ответ 4

Также можно использовать атрибут [FromHeader] для параметров веб-методов (или свойств в классе Model), которые следует отправлять в пользовательских заголовках. Что-то вроде этого:

[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")]string userIdentity)

По крайней мере, он отлично работает для ASP.NET Core 2.1 и Swashbuckle.AspNetCore 2.5.0.

Ответ 5

Вот более простой ответ для комбо-интерфейса ASP.NET Core Web Api/Swashbuckle, который не требует регистрации каких-либо пользовательских фильтров. Третий раз очарование ты знаешь :).

Добавление приведенного ниже кода в конфигурацию Swagger приведет к появлению кнопки "Авторизовать", которая позволит вам ввести маркер канала-носителя для отправки всех запросов. Не забудьте ввести этот токен как Bearer <your token here> при запросе.

Обратите внимание, что приведенный ниже код будет отправлять токен для любых запросов и операций, которые могут быть или не быть тем, что вы хотите.


    services.AddSwaggerGen(c =>
    {
        //...

        c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
        {
            Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
            Name = "Authorization",
            In = "header",
            Type = "apiKey"
        });

        c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
        {
            { "Bearer", new string[] { } }
        });

        //...
    }

Через эту ветку.

Ответ 6

Для тех, кто использует NSwag и нужен собственный заголовок:

app.UseSwaggerUi3(typeof(Startup).GetTypeInfo().Assembly, settings =>
      {
          settings.GeneratorSettings.IsAspNetCore = true;
          settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("custom-auth"));

          settings.GeneratorSettings.DocumentProcessors.Add(
              new SecurityDefinitionAppender("custom-auth", new SwaggerSecurityScheme
                {
                    Type = SwaggerSecuritySchemeType.ApiKey,
                    Name = "header-name",
                    Description = "header description",
                    In = SwaggerSecurityApiKeyLocation.Header
                }));
        });            
    }

Swagger UI будет включать кнопку авторизации.

Ответ 7

Я оказался здесь, потому что я пытался условно добавлять параметры заголовка в пользовательский интерфейс Swagger, основываясь на моем собственном атрибуте [Authentication], который я добавил в свой метод API. Следуя подсказке, которую @Corcus указал в комментарии, я смог получить свое решение, и, надеюсь, это поможет другим.

Используя Reflection, он проверяет, имеет ли метод, вложенный в apiDescription, нужный атрибут (MyApiKeyAuthenticationAttribute, в моем случае). Если это так, я могу добавить нужные параметры заголовка.

public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) {
    if (operation.parameters == null)
        operation.parameters = new List<Parameter>();


    var attributes = ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)
        ((apiDescription.ActionDescriptor).ActionBinding.ActionDescriptor)).MethodInfo
        .GetCustomAttributes(false);
    if(attributes != null && attributes.Any()) {
        if(attributes.Where(x => x.GetType() 
            == typeof(MyApiKeyAuthenticationAttribute)).Any()) {

            operation.parameters.Add(new Parameter {
                name = "MyApiKey",
                @in = "header",
                type = "string",
                description = "My API Key",
                required = true
            });
            operation.parameters.Add(new Parameter {
                name = "EID",
                @in = "header",
                type = "string",
                description = "Employee ID",
                required = true
            });
        }
    }


}

Ответ 8

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: это решение не использует заголовок.

Если кто-то ищет ленивый способ (также в WebApi), я бы предложил:

public YourResult Authorize([FromBody]BasicAuthCredentials credentials)

Вы не получаете от заголовка, но по крайней мере у вас есть легкая альтернатива. Вы всегда можете проверить объект на ноль и механизм возврата к заголовку.

Ответ 9

Golang/go-swagger пример: https://github.com/go-swagger/go-swagger/issues/1416

// swagger:parameters opid
type XRequestIdHeader struct {
    // in: header
    // required: true
    XRequestId string 'json:"X-Request-Id"'
}

...
    // swagger:operation POST /endpoint/ opid
    // Parameters:
    // - $ref: #/parameters/XRequestIDHeader