我创建了一个使用个人帐户安全的asp.net webapi应用程序,以便默认启用Bearer令牌。它工作正常,因此我可以毫无问题地在Postman中测试它们。
当我尝试通过Swashbuckle集成Swagger UI时,问题就出现了。我通过以下方式安装了Swashbuckle:
Install-Package Swashbuckle
然后更改 SwaggerConfig.cs :
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.ApiKey("Token")
.Description("Filling bearer token here")
.Name("Authorization")
.In("header");
}
.EnableSwaggerUi(c =>
{
c.EnableApiKeySupport("Authorization", "header");
};
启动我的申请并填写Bearer令牌:
但是当我运行需要授权的api请求时,它不起作用。这是截图:
将承销令牌添加到标头中的授权。但我仍然得到错误401.我想知道是否因为令牌被编码(SPACE被%20取代)?任何的想法?感谢。
顺便说一句,我想知道如何在我的Swagger文档中添加 / token ,以便我可以在Swagger UI中获取令牌。
答案 0 :(得分:18)
下面详述的问题现已在Swashbuckle v5.5.0中解决。
刚遇到完全相同的问题。我认为根本原因是Swashbuckle's source code中的这一行:
var key = encodeURIComponent($('#input_apiKey')[0].value);
这是HTML输入字段的值通过URL编码将空格转换为%20
的位置。我打算在Swashbuckle repo on GitHub中打开一个问题。
在解决该问题之前,这里有一个解决方法,它基于使用注入Swagger UI的Javascript文件替换上述行:
在安装了Swashbuckle的项目中,创建一个新文件夹并将其命名为“Swagger”。
在新文件夹中创建一个名为“SwaggerUiCustomization.js”的新Javascript文件,并将此脚本放入其中:
(function () {
function addApiKeyAuthorization() {
var key = $('#input_apiKey')[0].value;
if (key && key.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization(swashbuckleConfig.apiKeyName, key, swashbuckleConfig.apiKeyIn);
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
log("added key " + key);
}
}
$('#input_apiKey').change(addApiKeyAuthorization);
})();
在解决方案资源管理器中,选择文件并按Alt + Enter编辑其属性。在 Properties 窗口中,将文件的 Build Action 更改为 Embedded Resource 。
在SwaggerConfig.cs文件中,在EnableSwaggerUi()
代码块中添加以下行:
c.InjectJavaScript(thisAssembly,
"<Project_Default_Namespace>.Swagger.SwaggerUiCustomization.js");
当然,请确保将<Project_Default_Namespace>
替换为项目的默认命名空间。
运行项目并在文本框中输入“Bearer”。当您调用控制器操作时,您应该在服务器端获得完全相同的值 - 使用空格而不是%20%
。
答案 1 :(得分:5)
在asp.net框架Web API中,我能够在UI上添加Bearer令牌,并通过两种不同的方式使其正常工作。
添加操作拟合器。创建以下类:
public class AuthorizationHeaderParameterOperationFilter : 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 = "Authorization",
@in = "header",
description = "access token",
required = false,
type = "string",
@default = "Bearer "
});
}
}
,现在在SwaggerConfig.cs中添加以下内容:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
// other settings
c.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
})
.EnableSwaggerUi(c =>
{
// UI configurations
});
我们还可以使用DocumentFilter来迭代所有操作并添加标头,在下面的示例中,我们跳过实际上使用用户名和密码并首次给出令牌的操作:
public class SwaggerPathDescriptionFilter : IDocumentFilter
{
private string tokenUrlRoute = "Auth";
// the above is the action which returns token against valid credentials
private Dictionary<HeaderType, Parameter> headerDictionary;
private enum HeaderType { TokenAuth };
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
CreateHeadersDict();
var allOtherPaths = swaggerDoc.paths.Where(entry => !entry.Key.Contains(tokenUrlRoute)) //get the other paths which expose API resources and require token auth
.Select(entry => entry.Value)
.ToList();
foreach (var path in allOtherPaths)
{
AddHeadersToPath(path, HeaderType.TokenAuth);
}
}
/// <summary>
/// Adds the desired header descriptions to the path's parameter list
/// </summary>
private void AddHeadersToPath(PathItem path, params HeaderType[] headerTypes)
{
if (path.parameters != null)
{
path.parameters.Clear();
}
else
{
path.parameters = new List<Parameter>();
}
foreach (var type in headerTypes)
{
path.parameters.Add(headerDictionary[type]);
}
}
/// <summary>
/// Creates a dictionary containin all header descriptions
/// </summary>
private void CreateHeadersDict()
{
headerDictionary = new Dictionary<HeaderType, Parameter>();
headerDictionary.Add(HeaderType.TokenAuth, new Parameter() //token auth header
{
name = "Authorization",
@in = "header",
type = "string",
description = "Token Auth.",
required = true,
@default = "Bearer "
});
}
}
然后我们需要在SwaggerConfig.cs中重新搅拌它:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
// other settings
c.DocumentFilter<SwaggerPathDescriptionFilter>();
})
.EnableSwaggerUi(c =>
{
// UI configurations
});
现在,我们将在swagger UI中看到标头的Token输入,例如:
答案 2 :(得分:3)
注意:此示例使用Json Web令牌。
可以设置您的代码,因此授权字符串中不需要“ Bearer”。
WebApi项目中用于检索令牌的代码(请参见下面的代码段中的 token = ... ):
private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
{
token = null;
IEnumerable<string> authzHeaders;
if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
{
return false;
}
var bearerToken = authzHeaders.ElementAt(0);
token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
return true;
}
Swagger ApiKey:
c.ApiKey("Authorization")
.Description("Filling bearer token here")
.Name("Bearer")
.In("header");
Swagger启用ApiKey支持:
c.EnableApiKeySupport("Authorization", "header");