web-dev-qa-db-fra.com

Comment envoyer des en-têtes personnalisés avec des demandes dans l'interface utilisateur Swagger?

J'ai des points de terminaison dans l'API - /user/login, /products.

Dans Swagger UI, je poste email et password sur /user/login et, en réponse, je reçois une chaîne token.

Ensuite, je peux copier le jeton de la réponse et l'utiliser comme valeur d'en-tête Authorization dans les demandes adressées à toutes les URL si elles sont présentes et à /products à titre d'exemple.

Devrais-je créer une entrée de texte manuellement quelque part sur la page de l'interface utilisateur Swagger, puis placer le jeton à cet endroit et injecter les requêtes d'une manière ou d'une autre ou existe-t-il des outils pour mieux le gérer?

48
Sergei Basharov

Vous pouvez ajouter un paramètre d'en-tête à votre demande et Swagger-UI l'affichera sous la forme d'une zone de texte modifiable:

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

Vous pouvez également ajouter une définition de sécurité de type 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

L'objet securityDefinitions définit les schémas de sécurité.

L'objet security (appelé "exigences de sécurité" dans Swagger – OpenAPI) applique un schéma de sécurité à un contexte donné. Dans notre cas, nous l'appliquons à l'intégralité de l'API en déclarant que l'exigence de sécurité est un niveau supérieur. Nous pouvons éventuellement le remplacer dans des éléments de chemin et/ou des méthodes individuels.

Ce serait le moyen privilégié de spécifier votre schéma de sécurité. et il remplace le paramètre d'en-tête du premier exemple. Malheureusement, Swagger-UI ne propose pas de zone de texte pour contrôler ce paramètre, du moins lors de mes tests jusqu'à présent.

36
Ted Epstein

Dans ASP.net WebApi, le moyen le plus simple de passer un en-tête sur l'interface utilisateur Swagger consiste à implémenter la méthode Apply(...) sur l'interface IOperationFilter.

Ajoutez ceci à votre projet:

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
        });
    }
}

Dans SwaggerConfig.cs, enregistrez le filtre ci-dessus à l'aide de 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);
        });
}
45
ShaTin

Dans ASP.NET Core 2 Web API, en utilisant Swashbuckle.AspNetCore package 2.1.0, implémentez un 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[]{ } },
                }
            };
        }
    }
}

Dans Startup.cs, configurez une définition de sécurité et enregistrez le filtre personnalisé:

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>();
    });
}

Dans l’interface utilisateur Swagger, cliquez sur le bouton Autoriser et définissez la valeur du jeton.

Window to set value

Résultat:

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

Il est également possible d'utiliser l'attribut [FromHeader] pour les paramètres de méthodes Web (ou les propriétés d'une classe Model) qui doivent être envoyés dans des en-têtes personnalisés. Quelque chose comme ça:

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

Au moins, cela fonctionne bien pour ASP.NET Core 2.1 et Swashbuckle.AspNetCore 2.5.0.

2
Victor Sharovatov

Voici une réponse plus simple pour le combo ASP.NET Core Web Api/Swashbuckle, qui ne nécessite pas l’enregistrement de filtres personnalisés. La troisième fois est un charme, vous savez :).

L'ajout du code ci-dessous à votre configuration Swagger fera apparaître le bouton Autoriser, vous permettant de saisir un jeton de support à envoyer pour toutes les demandes. N'oubliez pas d'entrer ce jeton sous la forme Bearer <your token here> lorsque vous y êtes invité.

Notez que le code ci-dessous enverra le jeton pour toutes les demandes et opérations, qui peuvent ou non correspondre à vos souhaits.


    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[] { } }
        });

        //...
    }

Via ce fil .

2
Vlad Iliescu

Pour ceux qui utilisent NSwag et ont besoin d'un en-tête personnalisé:

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 inclura alors un bouton Autoriser .

1
Ofiris

AVERTISSEMENT: cette solution est pas en utilisant l'en-tête.

Si quelqu'un recherche une manière paresseuse-paresseuse (également dans WebApi), je suggérerais:

public YourResult Authorize([FromBody]BasicAuthCredentials credentials)

Vous ne recevez pas d'en-tête, mais au moins vous avez une alternative facile. Vous pouvez toujours vérifier si l'objet est null et utiliser le mécanisme d'en-tête.

0
Cesar

Je me suis retrouvé ici parce que j'essayais d'ajouter conditionnellement des paramètres d'en-tête dans l'interface utilisateur Swagger, en fonction de mon propre attribut [Authentication] que j'avais ajouté à ma méthode API. Suite à l’allusion que @Corcus a énumérée dans un commentaire, j’ai pu déduire ma solution et, espérons-le, aider les autres.

À l'aide de Reflection, il vérifie si la méthode imbriquée dans apiDescription a l'attribut souhaité (MyApiKeyAuthenticationAttribute, dans mon cas). Si c'est le cas, je peux ajouter les paramètres d'en-tête souhaités.

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
            });
        }
    }


}
0
InbetweenWeekends

Exemple 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
0
Qiang Li