如何在Swagger UI中发送带有请求的自定义标头?


79

我在API中一些端点- ,。/user/login/products

在扬鞭UI我交的email,并password/user/login和为响应我收到一个token字符串。

然后,我可以从响应中复制令牌,并希望将其用作Authorization请求中的标头值到所有url(如果存在),并/products作为示例。

我应该在Swagger UI页面上的某个位置手动创建文本输入,然后将令牌放到那里并以某种方式注入请求中,或者是否有工具可以更好地管理它?

Answers:


54

您可以在请求中添加标头参数,并且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

带有auth param文本框的Swagger-UI

您还可以添加带有类型的安全性定义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至少在到目前为止的测试中没有提供文本框来控制此参数。


1
我正在python模块中定义参数,该模块使用模型定义端点,然后使用这些模型RequestParse在swagger文档中添加输入字段。该文本文件如何以及在何处添加`-name:auth`?
Chang Zhao

61

在ASP.net WebApi中,在Swagger UI上传递标头的最简单方法是Apply(...)IOperationFilter接口上实现该方法。

将此添加到您的项目:

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<>()以下命令从上方注册过滤器:

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

1
您好,谢谢分享,这正是我所需要的。是否可以针对某些API方法禁用它?例如,用户登录名不需要传递该标头作为返回的Auth令牌。这会将'MyHeaderField'添加到所有API方法Swagger文档中。
尼尔·霍奇斯

@NeilHodges你明白了吗。我什至在寻找它。
gee'K'iran

2
@ gee'K'iran您可以通过检查operation和apiDescription参数并选择是否添加标题来有选择地应用该功能。
Corcus

@Corcus明白了。非常感谢。
gee'K'iran '17

20

在中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"

它是哪个版本?在大方的2.4.0中找不到“授权”按钮。
Don G.

9

也可以将[F​​romHeader]属性用于应在自定义标头中发送的网络方法参数(或Model类中的属性)。像这样:

[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")]string userIdentity)

至少它对于ASP.NET Core 2.1和Swashbuckle.AspNetCore 2.5.0正常工作。


1
这仅适用于MVC,不适用于Web Api解决方案(至少我认为是这样,因为它在我的Web Api解决方案上失败了)
bleh10

@ bleh10任何细节为什么它不能为您解决方案?对于我的Web API项目,它可以正常工作。
维克多·沙罗瓦托夫

不知道为什么,这迫使我添加了mvc库,当我对VS感到困惑时,明天我将重新检查,因为我今天不在工作,并且会添加我遇到的错误!
bleh10 '18

我的立场是正确的,我只是再次尝试了一下,它仍然起作用,唯一的问题是现在我必须添加“ System.Web.Http”。在HttpGET和route以及FromBody之前,这有点烦人,但到目前为止是最好的解决方案!编辑:一个更好的解决方案(不确定为什么我以前没有考虑过),所以我不重新编辑所有控制器是添加Microsoft.AspNetCore.Mvc。在FromHeader之前,现在一切正常!
bleh10

1
关于添加“ System.Web.Http”。在HttpGET和route和FromBody之前-您可以对该名称空间使用“ using”指令,以避免出现重复的代码。因此,只需using System.Web.Http;在定义控制器的文件开头添加。
维克多·沙罗瓦托夫

3

这是ASP.NET Core Web Api / Swashbuckle组合的简单答案,不需要您注册任何自定义过滤器。您知道第三次的魅力:)。

将以下代码添加到Swagger配置中,将显示“授权”按钮,从而允许您输入要为所有请求发送的承载令牌。不要忘记按要求输入此令牌Bearer <your token here>

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


    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[] { } }
        });

        //...
    }

通过这个线程


2

我到这里结束了,因为我试图根据[Authentication]添加到API方法中的我自己的属性在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密钥的.Net核心2.1 c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "ApiKeyAuth", new string[0] } }); stackoverflow.com/questions/49908577/...
SA。

1

对于那些使用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随后将包含一个Authorize按钮。


0

免责声明:此解决方案使用Header。

如果有人正在寻找一种懒惰-懒惰的方式(同样在WebApi中),我建议:

public YourResult Authorize([FromBody]BasicAuthCredentials credentials)

您不是从标题中获取信息,但是至少您有一个简单的选择。您始终可以检查对象是否为null并回退到标头机制。


0

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.