Як надіслати власні заголовки із запитами в інтерфейсі Swagger?


80

У мене є деякі кінцеві точки в API - /user/login,/products .

У Сваггер інтерфейс I поста emailі passwordдо /user/loginі у відповідь я отримуюtoken рядок.

Потім я можу скопіювати маркер із відповіді і хочу використовувати його як Authorizationзначення заголовка в запитах на всі URL-адреси, якщо він присутній, і /productsяк приклад.

Чи слід мені створювати введення тексту вручну десь на сторінці інтерфейсу Swagger, а потім помістити туди маркер і якось вводити в запити, чи є інструменти для кращого управління?

Відповіді:


56

Ви можете додати параметр заголовка до свого запиту, і 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 з текстовим полем auth param

Ви також можете додати визначення безпеки з типом 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 не пропонує текстового поля для управління цим параметром, принаймні під час мого тестування на даний момент.


1
Я визначаю параметри в модулі python, який визначає кінцеві точки, використовуючи моделі, які потім я також використовую RequestParseдля додавання полів введення в документацію обміну. Як і де цей текстовий файл додати `- name: auth`?
Чанг Чжао

61

В ASP.net WebApi найпростіший спосіб передачі заголовка в інтерфейсі Swagger - це реалізація 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);
        });
}

1
Привіт, дякую, що поділився цим, це саме те, що мені потрібно. Чи є спосіб вимкнути його для певних методів API? Наприклад, для входу користувача не потрібно буде передавати цей заголовок, оскільки він повертає маркер Auth. Це додавання "MyHeaderField" до всіх методів API Swagger.
Ніл Ходжес,

@NeilHodges ти це зрозумів. Я навіть шукаю це.
gee'K'iran

2
@ gee'K'iran Ви можете вибірково застосувати функціональність, перевіривши параметри роботи та apiDescription та вибравши додавання заголовка чи ні.
Коркус,

@Corcus Зрозумів. Дуже дякую.
gee'K'iran

20

За ASP.NET Core 2 Web APIдопомогою пакета Swashbuckle.AspNetCore 2.1.0 реалізуйте 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 натисніть кнопку Авторизувати та встановіть значення для маркера.

Вікно для встановлення значення

Результат:

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

Яка це вишукана версія? Тут у swagger 2.4.0 не вдається знайти кнопку Авторизувати.
Дон Г.

10

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

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

Принаймні, він чудово працює для ASP.NET Core 2.1 та Swashbuckle.AspNetCore 2.5.0.


1
Це працює лише з рішенням MVC, а не з рішенням Web Api (принаймні, я так думаю, оскільки воно не вдалося на моєму рішенні Web Api)
bleh10

1
@ bleh10 будь-які подробиці, чому це не вдається для вашого рішення? Для мого проекту веб-API це чудово працює.
Віктор Шароватов,

Не впевнений, чому, це змусило мене додати бібліотеку mvc, і коли я зробив VS, я заплутався, завтра перевірте погану перевірку, оскільки сьогодні я не на роботі, і додасть помилку, з якою я зіткнувся!
bleh10

Я стою виправлений, я просто спробував ще раз, і це спрацювало, єдина проблема полягає в тому, що тепер я повинен додати "System.Web.Http". перед HttpGET і route та FromBody, що досить дратує, але найкраще рішення поки що! Редагувати: Ще кращим рішенням (не впевнений, чому я раніше про це не думав), тому я не редагую всі свої контролери, є додавання Microsoft.AspNetCore.Mvc. до FromHeader і зараз все працює!
bleh10

1
Щодо додавання "System.Web.Http." перед HttpGET і route та FromBody - ви можете використовувати директиву "using" для цього простору імен, щоб уникнути цього повторюваного коду. Тож просто додайте using System.Web.Http;на початку файлу, де визначено ваш контролер.
Віктор Шароватов

3

Ось більш проста відповідь на комбінацію 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[] { } }
        });

        //...
    }

Через цю нитку .


2

Я опинився тут, тому що намагався умовно додати параметри заголовка в інтерфейс 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
            });
        }
    }


}

Для тих, хто намагається використовувати API Key .Net core 2.1 c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "ApiKeyAuth", new string[0] } }); stackoverflow.com/questions/49908577/…
SA.

1

Для тих, хто використовує 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 включатиме кнопку Авторизувати .


0

ЗАМОВЛЕННЯ: це рішення не є використовує Header.

Якщо хтось шукає ліниво-ледачий спосіб (також у WebApi), я б запропонував:

public YourResult Authorize([FromBody]BasicAuthCredentials credentials)

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.