如何在 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 中,我将 emailpassword 发布到 /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&lt;T&gt;()从上面注册过滤器:

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 &lt;your token here&gt;

请注意,下面的代码将为任何和所有请求和操作发送令牌,这可能是也可能不是您想要的。


    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.1 c.AddSecurityRequirement(new Dictionary&lt;string, IEnumerable&lt;string&gt;&gt; "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 UI

是否可以在 Swagger ui 之前添加登录页面?

如何让 Swagger 在生成的 HTML(在 Swagger UI 页面中)中添加新行?

在 Swagger UI 中,如何自定义 body 输入 ui(模型架构 UI)

如何使用 springfox 在 Swagger UI 中绕过授权

是否可以在 Axios 中发送带有 JSON 正文的 get 请求?