如何发送自定义头与请求在 Swagger UI?

我在 API-/user/login/products中有一些端点。

在 Swagger UI 中,我将 emailpassword发布到 /user/login,作为响应,我收到一个 token字符串。

然后,我可以从响应中复制令牌,并希望在请求中使用它作为 Authorization头值,如果它存在,则将其用于所有 url,并以 /products为例。

我是否应该在 Swagger UI 页面的某个地方手动创建一个文本输入,然后将令牌放在那里并以某种方式注入到请求中,或者是否有更好的工具来管理它?

231141 次浏览

您可以添加一个头参数到您的请求,并且 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。我们可以选择在各个路径项和/或方法中重写它。

This would be the preferred way to specify your security scheme; and it replaces the header parameter from the first example. Unfortunately, Swagger-UI doesn't offer a text box to control this parameter, at least in my testing so far.

在 ASP.NET Web API 中,在 Swagger UI 上传递标头的最简单方法是在 操作过滤器接口上实现 Apply(...)方法。

Add this to your project:

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, register the filter from above using 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);
});
}

我最终来到这里是因为我试图在 Swagger UI 中有条件地添加头参数,这是基于我自己添加到 API 方法中的 [Authentication]属性。根据@Corcus 在评论中列出的提示,我得到了我的解决方案,希望它能帮助其他人。

使用反射,它检查嵌套在 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
});
}
}




}

ASP.NET Core 2 Web API中,使用 虚张声势 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>();
});
}

In Swagger UI, click on Authorize button and set value for token.

Window to set value

Result:

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

For those who use NSwag and need a custom header:

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

然后,史瓦格 UI 将包括一个 授权按钮。

免责声明: 此解决方案是使用 Header 的 没有

如果有人正在寻找一种懒惰-懒惰的方式(同样在 WebApi 中) ,我会建议:

public YourResult Authorize([FromBody]BasicAuthCredentials credentials)

你没有从头部获得,但至少你有一个简单的替代品。 您总是可以检查对象是否为 null 并回退到头机制。

也可以对 web 方法参数(或 Model 类中的属性)使用属性[ FromHeader ] ,这些参数应该在自定义头中发送。就像这样:

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

至少它在 ASP.NET Core 2.1和 Swashuckle. AspNetCore 2.5.0上运行良好。

这里有一个更简单的 ASP.NET Core Web Api/Swashuckle 组合的答案,它不需要注册任何自定义过滤器。你知道,第三次总是有好处的:)。

将下面的代码添加到您的 Swagger 配置中将会显示 Authorize 按钮,允许您输入一个持有者令牌以发送所有请求。当被问及时,不要忘记以 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[] { } }
});


//...
}


通过 这根线

Golang/go-swagger 范例: ABc0

// 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

Update for OpenAPI 3, library Swashbuckle.AspNetCore. Correct code sample is provifded by this source: https://codeburst.io/api-security-in-swagger-f2afff82fb8e

与 JWT Bearer 一起使用时,正确的代码是:

services.AddSwaggerGen(c =>
{
// configure SwaggerDoc and others


// add JWT Authentication
var securityScheme = new OpenApiSecurityScheme
{
Name = "JWT Authentication",
Description = "Enter JWT Bearer token **_only_**",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "bearer", // must be lower case
BearerFormat = "JWT",
Reference = new OpenApiReference
{
Id = JwtBearerDefaults.AuthenticationScheme,
Type = ReferenceType.SecurityScheme
}
};
c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{securityScheme, new string[] { }}
});
}

我曾经看过一篇文章,其中有类似的 OpenAPI 2代码,但是因为错过了 Reference 定义而浪费了很多时间。这导致 SwashBuckle 生成了不正确的定义,并且没有包含 Authorization 头。因此,请仔细检查您使用的 OpenAPI 版本。

这就是我在.NET 6中实现它的方法

public class AddCustomHeaderParameter
: IOperationFilter
{
public void Apply(
OpenApiOperation operation,
OperationFilterContext context)
{
if (operation.Parameters is null)
{
operation.Parameters = new List<OpenApiParameter>();
}


operation.Parameters.Add(new OpenApiParameter
{
Name = "Custom Header",
In = ParameterLocation.Header,
Description = "Custom Header description",
Required = true,
});
}
}

最后

services.AddSwaggerGen(c =>
{
c.OperationFilter<AddCustomHeaderParameter>();
});

如果你使用的是 Nest.js,那么可以通过添加 addBearerAuth()来实现(可能在 main.ts中)。

...........


const config = new DocumentBuilder()
.setTitle('Your title')
.setDescription('Your description')
.setVersion('1.0')
.addBearerAuth()   // Add here
.build();


const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);


...........

添加这个属性后,我们可以通过以下方式从 Swagger 界面传递无记名令牌:

Swagger documentation

PS: 你必须在各自的控制器中使用 卫士来保护你的路由。

在 Features Swagger 中,为了显示 BearerAuth 的 Authorize 按钮在右上角,您的配置声明必须这样做:

{
...config, // other config parameters
specs: {
info: {
title: 'My API',
description: 'My API Documentation',
version: '2.0',
},
components: {
securityDefinitions: {
BasicAuth: {
type: 'basic'
},
BearerAuth: {
type: "http",
scheme: "bearer",
bearerFormat: "JWT"
}
},
},
security: {
BearerAuth: []
},
},
}

结果 enter image description here

更新一下这个给 Asp。Net Core 6 web API 和 Swashuckle。AspNetCore 6.4.0.出乎意料的简单。在我的例子中,所有的操作方法都需要标头,所以我得到了“必需”true。

第一,创建一个 Swashuckle。 AspNetCore。 SwaggerGen.IOperationFilter:

public class IMyCustomFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
operation.Parameters = new List<OpenApiParameter>();


operation.Parameters.Add(new OpenApiParameter()
{
Name= "MyCustomHeader",
In=ParameterLocation.Header,
Required=true
});
}
}

第二,告诉斯威格在配置服务时使用它:

builder.Services.AddSwaggerGen(config =>
{
//this causes Swagger to add an input so you can to add the value to header when you are executing an api method.
config.OperationFilter<IMyCustomFilter>();
});

第三,像往常一样调用斯威格:

        var app = builder.Build();


if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}