api - open - ¿Cómo enviar encabezados personalizados con solicitudes en Swagger UI?
swagger parameters response (8)
Tengo algunos puntos finales en la API - /user/login
, /products
.
En Swagger UI publico un correo email
y una password
para /user/login
y, como respuesta, recibo una cadena de token
.
Luego, puedo copiar el token de la respuesta y quiero usarlo como valor de encabezado de Authorization
en las solicitudes a todas las direcciones URL si está presente, y a /products
como ejemplo.
¿Debo crear una entrada de texto manualmente en algún lugar de la página de Swagger UI, luego colocar el token allí y de alguna manera insertar las solicitudes o hay herramientas para administrarlo de una mejor manera?
Aquí hay una respuesta más simple para el combo ASP.NET Core Web Api / Swashbuckle, que no requiere que se registre ningún filtro personalizado. La tercera vez es un encanto que sabes :).
Agregar el siguiente código a su configuración de Swagger hará que aparezca el botón Autorizar, lo que le permitirá ingresar un token de portador para todas las solicitudes. No olvide ingresar este token como Bearer <your token here>
cuando se le solicite.
Tenga en cuenta que el código a continuación enviará el token para todas y cada una de las solicitudes y operaciones, que pueden o no ser lo que desea.
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
});
}
}
}
A través de este hilo .
DESCARGO DE RESPONSABILIDAD: esta solución no está utilizando el encabezado.
Si alguien está buscando una manera perezosa-perezosa (también en WebApi), sugeriría:
public YourResult Authorize([FromBody]BasicAuthCredentials credentials)
No está recibiendo de cabecera, pero al menos tiene una alternativa fácil. Siempre se puede verificar el objeto en busca de un mecanismo nulo y de retroceso al encabezado.
En ASP.net WebApi, la forma más sencilla de pasar un encabezado a la interfaz de usuario de Swagger es implementar el método Apply (...) en la interfaz IOperationFilter .
Agrega esto a tu proyecto:
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
});
}
}
En SwaggerConfig.cs , registre el filtro desde arriba usando c.OperationFilter <T> () :
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);
});
}
En la ASP.NET Core 2 Web API
, utilizando el paquete Swashbuckle.AspNetCore 2.1.0, implemente 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[]{ } },
}
};
}
}
}
En Startup.cs, configure una definición de seguridad y registre el filtro personalizado:
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>();
});
}
En la interfaz de usuario de Swagger, haga clic en el botón Autorizar y establezca el valor para el token.
Resultado:
curl -X GET "http://localhost:5000/api/tenants" -H "accept: text/plain" -H "Authorization: Bearer ABCD123456"
Para aquellos que usan NSwag y necesitan un encabezado personalizado:
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[] { } }
});
//...
}
Swagger UI luego incluirá un botón Autorizar .
Puede agregar un parámetro de encabezado a su solicitud, y Swagger-UI lo mostrará como un cuadro de texto editable:
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
También puede agregar una definición de seguridad con el tipo 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
El objeto securityDefinitions define esquemas de seguridad.
El objeto de security
(llamado "requisitos de seguridad" en Swagger – OpenAPI), aplica un esquema de seguridad a un contexto dado. En nuestro caso, lo aplicamos a toda la API declarando que el requisito de seguridad es un nivel superior. Opcionalmente, podemos anularlo dentro de los elementos y / o métodos de ruta individuales.
Esta sería la forma preferida de especificar su esquema de seguridad; y reemplaza el parámetro de encabezado del primer ejemplo. Desafortunadamente, Swagger-UI no ofrece un cuadro de texto para controlar este parámetro, al menos en mis pruebas hasta ahora.
También es posible usar el atributo [FromHeader] para los parámetros de los métodos web (o propiedades en una clase de modelo) que deben enviarse en encabezados personalizados. Algo como esto:
[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")]string userIdentity)
Al menos funciona bien para ASP.NET Core 2.1 y Swashbuckle.AspNetCore 2.5.0.
Terminé aquí porque intentaba agregar condicionalmente parámetros de encabezado en la interfaz de usuario de Swagger, en base a mi propio atributo [Authentication]
que agregué a mi método API. Siguiendo la sugerencia que @Corcus incluyó en un comentario, pude derivar mi solución y espero que ayude a otros.
Usando Reflection, es verificar si el método anidado en la apiDescription
tiene el atributo deseado (MyApiKeyAuthenticationAttribute, en mi caso). Si lo hace, puedo anexar los parámetros de encabezado deseados.
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
}));
});
}