如何在 Swagger UI 中发送带有请求的自定义标头?
Posted
技术标签:
【中文标题】如何在 Swagger UI 中发送带有请求的自定义标头?【英文标题】:How to send custom headers with requests in Swagger UI? 【发布时间】:2017-05-02 00:39:04 【问题描述】:我在 API 中有一些端点 - /user/login
、/products
。
在 Swagger UI 中,我将 email
和 password
发布到 /user/login
,作为回复,我收到了 token
字符串。
然后,我可以从响应中复制令牌,并希望将其用作Authorization
标头值,用于对所有网址(如果存在)的请求,并以/products
为例。
我应该在 Swagger UI 页面的某处手动创建文本输入,然后将令牌放在那里并以某种方式注入请求,还是有工具可以更好地管理它?
【问题讨论】:
【参考方案1】:在 ASP.NET Web API 中,在 Swagger UI 上传入标头的最简单方法是在 IOperationFilter 接口上实现 Apply(...)
方法。
将此添加到您的项目中:
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<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);
);
【讨论】:
您好,感谢分享这个,这正是我所需要的。有没有办法为某些 API 方法禁用它?例如,用户登录不需要将该标头作为返回身份验证令牌传递。这将“MyHeaderField”添加到所有 API 方法 Swagger 文档中。 @NeilHodges 你明白了吗。我什至在寻找它。 @gee'K'iran 您可以通过检查 operation 和 apiDescription 参数并选择是否添加标头来选择性地应用该功能。 感谢您不包括命名空间。 我试过这个。客户标头位于 httpContext.Request.Headers 结果集的结果视图下,但是当我执行 var key = httpContext.Request.Headers.Where(z => z.Key == "CUSTOMKEY").FirstOrDefault();我得到的关键是[null,null]。有什么想法吗?【参考方案2】:你可以在你的请求中添加一个 header 参数,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
您还可以添加类型为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。我们可以选择在单个路径项和/或方法中覆盖它。
这将是指定安全方案的首选方式;它替换了第一个示例中的 header 参数。不幸的是,至少在我目前的测试中,Swagger-UI 没有提供文本框来控制这个参数。
【讨论】:
我在 python 模块中定义参数,该模块使用模型定义端点,然后我使用RequestParse
在 swagger 文档中添加输入字段。该文本文件如何以及在何处添加 `-name: auth` ?
@Ted,我们没有办法在 openapi2.0 中提供自定义的 json(object) 类型信息吗? this attempt fails to compile【参考方案3】:
在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 UI 中,单击“授权”按钮并设置令牌的值。
结果:
curl -X GET "http://localhost:5000/api/tenants" -H "accept: text/plain" -H "Authorization: Bearer ABCD123456"
【讨论】:
是哪个swagger版本?在 swagger 2.4.0 中找不到授权按钮。【参考方案4】:还可以将属性 [FromHeader] 用于应在自定义标头中发送的 Web 方法参数(或模型类中的属性)。像这样的:
[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")] string userIdentity)
至少它适用于 ASP.NET Core 2.1 和 Swashbuckle.AspNetCore 2.5.0。
【讨论】:
这只适用于 MVC 而不是 Web Api 解决方案(至少我是这么认为的,因为它在我的 Web Api 解决方案上失败了) @bleh10 任何详细信息为什么它对您的解决方案失败?对于我的 Web API 项目,它工作得很好。 不知道为什么,它迫使我添加mvc库,当我做VS时感到困惑,明天我会重新检查,因为我今天不上班,并会添加我遇到的错误!跨度> 我已经更正了,我只是再次尝试它并且它有效,唯一的问题是现在我必须添加“System.Web.Http”。在 HttpGET 和 route 和 FromBody 之前,这有点烦人,但迄今为止最好的解决方案!编辑:一个更好的解决方案(不知道为什么我以前没有想到它)所以我不重新编辑我所有的控制器是添加 Microsoft.AspNetCore.Mvc。在 FromHeader 之前,现在一切正常! 关于添加“System.Web.Http”。在 HttpGET 和 route 和 FromBody 之前 - 您可以对该命名空间使用“using”指令来避免这种重复的代码。因此,只需在定义控制器的文件开头添加using System.Web.Http;
。【参考方案5】:
这是 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[]
);
//...
通过this thread。
【讨论】:
【参考方案6】:我最终来到这里是因为我试图根据我添加到我的 API 方法中的 [Authentication]
属性有条件地在 Swagger UI 中添加标题参数。根据@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
);
【讨论】:
对于那些正在尝试使用 API Key .Net core 2.1c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> "ApiKeyAuth", new string[0] );
***.com/questions/49908577/…【参考方案7】:
对于那些使用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 UI 将包含一个 授权 按钮。
【讨论】:
【参考方案8】: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
【讨论】:
【参考方案9】:更新 OpenAPI 3,库 Swashbuckle.AspNetCore。此来源提供了正确的代码示例: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 的类似代码,但由于该示例错过了参考定义,因此浪费了很多时间。这导致 Swashbuckle 生成了不正确的定义并错过了包含 Authorizeation 标头。所以请仔细检查您使用的 OpenAPI 版本。
【讨论】:
【参考方案10】:免责声明:此解决方案不使用 Header。
如果有人正在寻找一种懒惰的方式(也在 WebApi 中),我建议:
public YourResult Authorize([FromBody]BasicAuthCredentials credentials)
你不是从标题中得到的,但至少你有一个简单的选择。 您始终可以检查对象是否为空并回退到标头机制。
【讨论】:
以上是关于如何在 Swagger UI 中发送带有请求的自定义标头?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Swagger 在生成的 HTML(在 Swagger UI 页面中)中添加新行?
在 Swagger UI 中,如何自定义 body 输入 ui(模型架构 UI)