Ich habe einige Endpunkte in der API - /user/login
, /products
.
In Swagger UI poste ich email
und password
zu /user/login
Und als Antwort erhalte ich einen token
String.
Dann kann ich das Token aus der Antwort kopieren und möchte es als Authorization
-Headerwert in Anfragen an alle URLs, sofern vorhanden, und als Beispiel an /products
Verwenden.
Soll ich irgendwo auf der Seite der Swagger-Benutzeroberfläche manuell eine Texteingabe erstellen, dann das Token dort ablegen und die Anforderungen irgendwie einfügen, oder gibt es Tools, um sie besser zu verwalten?
Sie können Ihrer Anfrage einen Header-Parameter hinzufügen, und Swagger-UI zeigt ihn als bearbeitbares Textfeld an:
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
Sie können auch eine Sicherheitsdefinition mit dem Typ apiKey
hinzufügen:
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
Das Objekt securityDefinitions
definiert Sicherheitsschemata.
Das Objekt security
(in Swagger-OpenAPI "Sicherheitsanforderungen" genannt) wendet ein Sicherheitsschema auf einen bestimmten Kontext an. In unserem Fall wenden wir es auf die gesamte API an, indem wir die Sicherheitsanforderung als oberste Ebene deklarieren. Wir können es optional innerhalb einzelner Pfadelemente und/oder Methoden überschreiben.
Dies ist die bevorzugte Methode, um Ihr Sicherheitsschema anzugeben. und es ersetzt den Header-Parameter aus dem ersten Beispiel. Leider bietet Swagger-UI, zumindest in meinen bisherigen Tests, kein Textfeld zur Steuerung dieses Parameters.
In ASP.net WebApi können Sie einen Header auf der Swagger-Benutzeroberfläche am einfachsten übergeben, indem Sie die Apply(...)
-Methode auf der IOperationFilter -Schnittstelle implementieren.
Fügen Sie dies zu Ihrem Projekt hinzu:
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
});
}
}
In SwaggerConfig.cs registrieren Sie den Filter von oben mit 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);
});
}
Im ASP.NET Core 2 Web API
implementieren Sie mit Swashbuckle.AspNetCore Paket 2.1.0 einen 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[]{ } },
}
};
}
}
}
Konfigurieren Sie in Startup.cs eine Sicherheitsdefinition und registrieren Sie den benutzerdefinierten Filter:
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>();
});
}
Klicken Sie in der Swagger-Benutzeroberfläche auf die Schaltfläche Autorisieren und legen Sie den Wert für das Token fest.
Ergebnis:
curl -X GET "http://localhost:5000/api/tenants" -H "accept: text/plain" -H "Authorization: Bearer ABCD123456"
Es ist auch möglich, das Attribut [FromHeader] für Webmethodenparameter (oder Eigenschaften in einer Model-Klasse) zu verwenden, die in benutzerdefinierten Headern gesendet werden sollen. Etwas wie das:
[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")]string userIdentity)
Zumindest funktioniert es gut für ASP.NET Core 2.1 und Swashbuckle.AspNetCore 2.5.0.
Hier ist eine einfachere Antwort für die Kombination aus ASP.NET Core-Web-API und Swashbuckle, bei der Sie keine benutzerdefinierten Filter registrieren müssen. Das dritte Mal ist ein Zauber, den du kennst :).
Wenn Sie den folgenden Code zu Ihrer Swagger-Konfiguration hinzufügen, wird die Schaltfläche "Autorisieren" angezeigt, mit der Sie einen Inhaber-Token eingeben können, der für alle Anforderungen gesendet werden soll. Vergessen Sie nicht, dieses Token als Bearer <your token here>
wenn gefragt.
Beachten Sie, dass der folgende Code das Token für alle Anforderungen und Vorgänge sendet, die Ihren Wünschen entsprechen oder nicht.
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[] { } }
});
//...
}
Über dieser Thread .
Für diejenigen, die NSwag verwenden und einen benutzerdefinierten Header benötigen:
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
}));
});
}
Die Benutzeroberfläche von Swagger enthält dann eine Schaltfläche Autorisieren .
HAFTUNGSAUSSCHLUSS: Diese Lösung ist nicht mit Header.
Wenn jemand nach einer faulen Art sucht (auch in WebApi), würde ich vorschlagen:
public YourResult Authorize([FromBody]BasicAuthCredentials credentials)
Sie kommen nicht vom Kopf, haben aber zumindest eine einfache Alternative. Sie können das Objekt immer auf Null und einen Fallback-to-Header-Mechanismus prüfen.
Ich bin hier gelandet, weil ich versucht habe, Header-Parameter in der Swagger-Benutzeroberfläche bedingt hinzuzufügen, basierend auf meinem eigenen [Authentication]
Attribut, das ich meiner API-Methode hinzugefügt habe. Dem Hinweis folgend, dass @Corcus in einem Kommentar aufgeführt ist, konnte ich meine Lösung ableiten und hoffe, dass es anderen helfen wird.
Mit Reflection wird überprüft, ob die in apiDescription
verschachtelte Methode das gewünschte Attribut (in meinem Fall MyApiKeyAuthenticationAttribute) hat. In diesem Fall kann ich die gewünschten Header-Parameter anhängen.
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
});
}
}
}
Golang/go-swagger-Beispiel: 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