在Swashbuckle中启用持票人令牌(Swagger文档)

时间:2016-08-18 03:58:01

标签: swagger swagger-ui swashbuckle

我创建了一个使用个人帐户安全的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令牌:

enter image description here

但是当我运行需要授权的api请求时,它不起作用。这是截图:

enter image description here

将承销令牌添加到标头中的授权。但我仍然得到错误401.我想知道是否因为令牌被编码(SPACE被%20取代)?任何的想法?感谢。

顺便说一句,我想知道如何在我的Swagger文档中添加 / token ,以便我可以在Swagger UI中获取令牌。

3 个答案:

答案 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文件替换上述行:

  1. 在安装了Swashbuckle的项目中,创建一个新文件夹并将其命名为“Swagger”

  2. 在新文件夹中创建一个名为“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);
    })();
    
  3. 在解决方案资源管理器中,选择文件并按Alt + Enter编辑其属性。在 Properties 窗口中,将文件的 Build Action 更改为 Embedded Resource

  4. 在SwaggerConfig.cs文件中,在EnableSwaggerUi()代码块中添加以下行: c.InjectJavaScript(thisAssembly, "<Project_Default_Namespace>.Swagger.SwaggerUiCustomization.js");
    当然,请确保将<Project_Default_Namespace>替换为项目的默认命名空间。

  5. 运行项目并在文本框中输入“Bearer”。当您调用控制器操作时,您应该在服务器端获得完全相同的值 - 使用空格而不是%20%

答案 1 :(得分:5)

在asp.net框架Web API中,我能够在UI上添加Bearer令牌,并通过两种不同的方式使其正常工作。

方法1:

添加操作拟合器。创建以下类:

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

方法2:

我们还可以使用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输入,例如:

enter image description here

答案 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");

将令牌粘贴到Swagger UI中的Api_Key表单元素中: enter image description here

它在Swagger中的请求标头中的外观: enter image description here