我在ASP.NET Web API上使用Swashbuckle和Swagger。我正在尝试通过Swagger UI找到一种传递包含Bearer令牌的Authorization标头的方法。我一直在寻找,但所有答案似乎都指向this链接。
但是,这假定标题的内容是预先知道的。我真的需要一种方法来改变Swagger UI中的标题(在点击'试一试!'按钮之前),因为Bearer标记每小时都会到期。类似于Postman允许您添加标题的方式。
这似乎是一个如此荒谬的简单问题,但答案是什么?
我们在项目中遇到了同样的问题。我还想将标头参数添加到Swagger UI网站。这就是我们这样做的方式:
1.定义OperationFilter类每次构建Swagger时,都会对每个API操作执行OperationFilters。根据您的代码,将根据您的过滤器检查操作。在此示例中,我们在每个操作上都需要header参数,但在具有AllowAnonymous属性的操作上使其成为可选项。
public class AddAuthorizationHeader : IOperationFilter
{
/// <summary>
/// Adds an authorization header to the given operation in Swagger.
/// </summary>
/// <param name="operation">The Swashbuckle operation.</param>
/// <param name="schemaRegistry">The Swashbuckle schema registry.</param>
/// <param name="apiDescription">The Swashbuckle api description.</param>
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (operation == null) return;
if (operation.parameters == null)
{
operation.parameters = new List<Parameter>();
}
var parameter = new Parameter
{
description = "The authorization token",
@in = "header",
name = "Authorization",
required = true,
type = "string"
};
if (apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
{
parameter.required = false;
}
operation.parameters.Add(parameter);
}
}
2.告诉Swagger使用此OperationFilter在SwaggerConfig中,只需添加操作过滤器,如下所示:
c.OperationFilter<AddAuthorizationHeader>();
希望这可以帮助你!
创建一个实现IOperationFilter
的新操作过滤器。
public class AuthorizationHeaderOperationFilter : IOperationFilter
{
/// <summary>
/// Adds an authorization header to the given operation in Swagger.
/// </summary>
/// <param name="operation">The Swashbuckle operation.</param>
/// <param name="context">The Swashbuckle operation filter context.</param>
public void Apply(Operation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
{
operation.Parameters = new List<IParameter>();
}
var authorizeAttributes = context.ApiDescription
.ControllerAttributes()
.Union(context.ApiDescription.ActionAttributes())
.OfType<AuthorizeAttribute>();
var allowAnonymousAttributes = context.ApiDescription.ActionAttributes().OfType<AllowAnonymousAttribute>();
if (!authorizeAttributes.Any() && !allowAnonymousAttributes.Any())
{
return;
}
var parameter = new NonBodyParameter
{
Name = "Authorization",
In = "header",
Description = "The bearer token",
Required = true,
Type = "string"
};
operation.Parameters.Add(parameter);
}
}
在Startup.cs
文件中配置服务。
services.ConfigureSwaggerGen(options =>
{
options.OperationFilter<AuthorizationHeaderOperationFilter>();
});
你可以用不同的方式来做,这取决于你如何收集Authorization
标题,以及你是否希望代码处理所有内容,或者你是否希望用户能够输入他们想要的Authorization
标题。
当我第一次尝试这个时,我能够在每个端点的参数字段区域显示一个Authorization
头文本,用户可以在其中键入Authorization
标题,但这不是我想要的。
在我的情况下,我必须使用用户的cookie向/token
端点发送请求,以获得有效的Authorization
令牌。所以我做了很多事情来实现这个目标。
首先在SwaggerConfig.cs
我取消注释c.BasicAuth()
以获得API模式的基本身份验证方案,我还注入了一个自定义的index.html
页面,我插入了一个AJAX请求,以便使用用户的cookie(Authorization
代码如下所示)获取index.html
令牌:
public static void Register() {
System.Reflection.Assembly thisAssembly = typeof(SwaggerConfig).Assembly;
System.Web.Http.GlobalConfiguration.Configuration
.EnableSwagger(c => {
...
c.BasicAuth("basic").Description("Bearer Token Authentication");
...
})
.EnableSwaggerUi(c => {
...
c.CustomAsset("index", thisAssembly, "YourNamespace.index.html");
...
});
}
然后前往here下载swashbuckle index.html
,我们将自定义插入Authorization
标题。
下面我简单地使用有效的cookie对我的/token
端点进行AJAX调用,获取Authorization
令牌,然后将其放在wagx上与window.swaggerUi.api.clientAuthorizations.add()
一起使用:
...
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
$.ajax({
url: url + 'token'
, type: 'POST'
, data: { 'grant_type': 'CustomCookie' }
, contentType: 'application/x-www-form-urlencoded'
, async: true
, timeout: 60000
, cache: false
, success: function(response) {
console.log('Token: ' + response['token_type'] + ' ' + response['access_token']);
window.swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("Authorization", response['token_type'] + ' ' + response['access_token'], "header"));
}
, error: function(request, status, error) {
console.log('Status: ' + status + '. Error: ' + error + '.');
}
});
我从AJAX调用中删除了一些内容以使其更简单,显然您的实现可能会有所不同,具体取决于您如何收集Authorization
令牌和内容,但这会让您有所了解。如果您有任何具体问题或疑问,请与我们联系。
*编辑:没有注意到你确实希望用户输入他们的Authorization
标题。在这种情况下,这很容易。我用过this帖子。只需创建以下类来完成工作:
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 = "Foo-Header",
@in = "header",
type = "string",
required = true
});
}
}
然后将类添加到我的SwaggerConfig
中,如下所示:
...
c.OperationFilter<AddRequiredHeaderParameter>();
...