【问题标题】:How to pass custom headers while calling a web api using Swagger(Swashbuckle)如何在使用 Swagger(Swashbuckle) 调用 Web api 时传递自定义标头
【发布时间】:2018-12-12 17:00:40
【问题描述】:

我们正在使用 Swashbuckle 来记录我们的 web api 并使用它来测试我们的 web api。我想知道如何使用 Swagger UI 为每个请求传递具有不同值的多个自定义标头。

我在互联网上看到类似下面的答案以在 Swagger UI 中传递标题,但无法理解它。令人困惑的是 SwaggerExtensions 文件。这个文件的用途是什么,为什么在js文件的限定名中会提到这个文件。

1.添加名为“SwaggerExtensions”的新文件,然后添加名为“onComplete.js”的新JS文件,您必须将此文件的构建操作更改为“嵌入式资源”。

2.在文件“onComplete.js”中粘贴以下代码:

$('#input_apiKey').change(function () {

var key = $('#input_apiKey')[0].value;
if (key && key.trim() != "") {
key = "Bearer " + key;
window.authorizations.add("key", new ApiKeyAuthorization("Authorization",   key, "header"));
}
});

3.打开文件“SwaggerConfig.cs”并在注册方法中粘贴以下代码:

SwaggerUiConfig.Customize(c =>
{
 c.SupportHeaderParams = true;
 c.InjectJavaScript(typeof(SwaggerConfig).Assembly,        "AngularJSAuthentication.API.SwaggerExtensions.onComplete.js");
});

【问题讨论】:

    标签: asp.net-web-api swagger-ui


    【解决方案1】:

    swagger 的 Swashbuckles 实现读取 XML 代码 cmets 以生成所需的 swagger 规范。不幸的是,如果您需要授权标头(访问令牌)来发出请求,XML 代码 cmets 不会将此信息提供给 Swashbuckle。您必须在 swagger 规范生成期间手动注入这个新参数。

    Swashbuckle 提供了一个名为 IOperationFilter 的接口来应用新参数。实现这个接口看起来像这样。

    public class AddAuthorizationHeaderParameterOperationFilter: IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline();
            var isAuthorized = filterPipeline
                                             .Select(filterInfo => filterInfo.Instance)
                                             .Any(filter => filter is IAuthorizationFilter);
    
            var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
    
            if (isAuthorized && !allowAnonymous)
            {
                operation.parameters.Add(new Parameter {
                    name = "Authorization",
                    @in = "header",
                    description = "access token",
                    required = true,
                    type = "string"                    
                });
            }
        }
    }
    

    在您的 SwaggerConfig.cs 文件中,添加以下内容

    public class SwaggerConfig
    {
        public static void Register()
        {
            var thisAssembly = typeof(SwaggerConfig).Assembly;
    
            GlobalConfiguration.Configuration
                .EnableSwagger(c =>
    
    
                    c.SingleApiVersion("v1", "API").Description("An API ")
                                                            .TermsOfService("Some terms")
                                                            .Contact(cc => cc.Name("Team")
                                                            .Email("team@team.com"));
    
                    c.OperationFilter(() => new AuthorizationHeaderParameterOperationFilter()));
    
    
          }
     }
    

    【讨论】:

    • 但是,我想从 UI (Swagger-UI) 传递标头值。如何传递标头的值?
    • 谢谢@nimacs,这对我有用。虽然由于某种原因我的 operation.parameters 为空,但我添加了一个检查,如果它为空,则在添加所需参数之前将其初始化。
    • 您可能还需要在添加 operation.parameters 之前添加以下代码行: if (operation.parameters == null) operation.parameters = new List();
    【解决方案2】:

    Swashbuckle 建议使用 InjectJavaScript 来完成此操作。 https://github.com/domaindrivendev/Swashbuckle#injectjavascript

    我使用以下代码在 http 标头中添加不记名令牌以进行授权。

    httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) co
    .EnableSwaggerUi(c =>
        {
            c.InjectJavaScript(containingAssembly, "ProjectName.SwaggerUIEnableBearerToken.js");
        });
    

    SwaggerUIEnableBearerToken.js

    $(function () {
    $('#input_apiKey').attr("placeholder", "bearer token");
    $('#input_apiKey').off();
    $('#input_apiKey').change(function () {
        var token = this.value;
        if (token && token.trim() !== '') {
            token = 'Bearer ' + token;
            var apiKeyAuth = new window.SwaggerClient.ApiKeyAuthorization("Authorization", token, "header");
            window.swaggerUi.api.clientAuthorizations.add("token", apiKeyAuth);
            }
        }
    });
    })();
    

    从这个问题线程中查看更多信息: https://github.com/domaindrivendev/Swashbuckle/issues/222

    【讨论】:

    • 什么是包含组件?
    • 包含Assembly = typeof(SwaggerConfig).Assembly;其中 SwaggerConfig 是持有 swagger 配置的类。
    【解决方案3】:

    您可以使用 SwaggerUI 添加参数:

    swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("api_key", key, "header"));
    

    【讨论】:

      【解决方案4】:

      我在尝试添加包含一些身份验证信息的自定义标头时偶然发现了这个问题。 This article 建议在不注入 JavaScript(纯 .NET 方法)的情况下通过在配置 swagger 集成时提供 SecurityDefinition 来实现此目的:

      services.AddSwaggerGen(c =>
      {
          c.SwaggerDoc("v1.0", new Info { Title = "Main API v1.0", Version = "v1.0" });
      
          // Swagger 2.+ support
          var security = new Dictionary<string, IEnumerable<string>>
          {
              {"Bearer", new string[] { }},
          };
      
          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(security);
      });
      

      这总是在 API 级别或方法级别(某种登录)定义安全令牌,并且此令牌将用于所有后续请求,直到注销。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-28
        • 1970-01-01
        • 1970-01-01
        • 2018-05-13
        • 2018-07-29
        • 1970-01-01
        相关资源
        最近更新 更多