Swagger UI:通过自定义授权 header

Swagger UI: pass custom Authorization header

我在 ASP.NET Web API 上使用 Swashbuckle 和 Swagger。我试图找到一种方法来通过 Swagger UI 传递包含 Bearer 令牌的授权 header。我一直在四处寻找,但所有答案似乎都指向 this link。

但是,这假设 header 的内容是预先知道的。我真的需要一种方法来更改 Swagger UI 中的 header(就在点击 'Try it out!' 按钮之前),因为 Bearer 令牌每小时都会过期。类似于 Postman 允许您添加 headers.

的方式

看似简单得离谱的问题,但答案是什么?

根据您收集 Authorization header 的方式以及您是否希望代码处理所有内容,或者您​​是否希望用户能够输入任何内容,您可以采用不同的方式来完成Authorization header 他们想要。

当我第一次尝试这个时,我能够在每个端点的参数字段区域中显示 Authorization header 文本,用户可以在其中输入 Authorization header 但这不是我想要的。

在我的情况下,我必须使用用户的 cookie 向 /token 端点发送请求以获得有效的 Authorization 令牌。所以我做了很多事情来实现这个目标。

首先在 SwaggerConfig.cs 中,我取消注释 c.BasicAuth() 以将基本身份验证方案添加到 API 架构中,我还注入了自定义 index.html 页面,其中我插入了 AJAX 请求以获取 Authorization 令牌,使用用户的 cookie(index.html 代码如下所示):

public static void Register() {

    System.Reflection.Assembly thisAssembly = typeof(SwaggerConfig).Assembly;

    System.Web.Http.GlobalConfiguration.Configuration
                .EnableSwagger(c => {
                    ...

                    c.BasicAuth("basic").Description("Bearer Token Authentication");

                    ...
                })
                .EnableSwaggerUi(c => {
                    ...

                    c.CustomAsset("index", thisAssembly, "YourNamespace.index.html");

                    ...
                });
}

然后前往 here 下载我们将自定义的 swashbuckle index.html 以插入 Authorization header.

下面我简单地使用有效的 cookie 对我的 /token 端点进行 AJAX 调用,获取 Authorization 令牌,并将其交给 swagger 以与 [=29= 一起使用]:

...

function log() {
  if ('console' in window) {
    console.log.apply(console, arguments);
  }
}

$.ajax({
    url: url + 'token'
  , type: 'POST'
  , data: { 'grant_type': 'CustomCookie' }
  , contentType: 'application/x-www-form-urlencoded'
  , async: true
  , timeout: 60000
  , cache: false
  , success: function(response) {
        console.log('Token: ' + response['token_type'] + ' ' + response['access_token']);
        window.swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("Authorization", response['token_type'] + ' ' + response['access_token'], "header"));
    }
  , error: function(request, status, error) {
        console.log('Status: ' + status + '. Error: ' + error + '.');
    }
});

我从 AJAX 调用中删除了一些东西以使其更简单,显然你的实现可能会有所不同,具体取决于你如何收集你的 Authorization 令牌和东西,但这给了你一个主意。如果您有任何具体问题或疑问,请告诉我。

*编辑:没有注意到您实际上确实希望用户输入他们的 Authorization header。在那种情况下,这很容易。我用了thispost。只需创建以下 class 即可完成工作:

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 = "Foo-Header",
            @in = "header",
            type = "string",
            required = true
        });
    }
}

然后将 class 添加到我的 SwaggerConfig 中,如下所示:

...
c.OperationFilter<AddRequiredHeaderParameter>();
...

我们 运行 在我们的项目中遇到了同样的问题。我还想将 header 参数添加到 Swagger UI 网站。我们是这样做的:

1.定义一个 OperationFilter class 每次构建 Swagger 时,OperationFilters 都会在每个 API 操作上执行。根据您的代码,将根据您的过滤器检查操作。在此示例中,我们使每个操作都需要 header 参数,但在具有 AllowAnonymous 属性的操作中将其设为可选参数。

    public class AddAuthorizationHeader : IOperationFilter
    {
        /// <summary>
        /// Adds an authorization header to the given operation in Swagger.
        /// </summary>
        /// <param name="operation">The Swashbuckle operation.</param>
        /// <param name="schemaRegistry">The Swashbuckle schema registry.</param>
        /// <param name="apiDescription">The Swashbuckle api description.</param>
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            if (operation == null) return;

            if (operation.parameters == null)
            {
                operation.parameters = new List<Parameter>();
            }

            var parameter = new Parameter
            {
                description = "The authorization token",
                @in = "header",
                name = "Authorization",
                required = true,
                type = "string"
            };

            if (apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
            {
                parameter.required = false;
            }

            operation.parameters.Add(parameter);
        }
    }

2。告诉 Swagger 使用这个 OperationFilter 在SwaggerConfig中,只需添加操作过滤器应该使用如下:

    c.OperationFilter<AddAuthorizationHeader>();

希望对您有所帮助!

创建一个新的操作过滤器来实现 IOperationFilter

public class AuthorizationHeaderOperationFilter : IOperationFilter
{
    /// <summary>
    /// Adds an authorization header to the given operation in Swagger.
    /// </summary>
    /// <param name="operation">The Swashbuckle operation.</param>
    /// <param name="context">The Swashbuckle operation filter context.</param>
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
        {
            operation.Parameters = new List<IParameter>();
        }

        var authorizeAttributes = context.ApiDescription
            .ControllerAttributes()
            .Union(context.ApiDescription.ActionAttributes())
            .OfType<AuthorizeAttribute>();
        var allowAnonymousAttributes = context.ApiDescription.ActionAttributes().OfType<AllowAnonymousAttribute>();

        if (!authorizeAttributes.Any() && !allowAnonymousAttributes.Any())
        {
            return;
        }

        var parameter = new NonBodyParameter
        {
            Name = "Authorization",
            In = "header",
            Description = "The bearer token",
            Required = true,
            Type = "string"
        };

        operation.Parameters.Add(parameter);
    }
}

在您的 Startup.cs 文件中配置服务。

        services.ConfigureSwaggerGen(options =>
        {
            options.OperationFilter<AuthorizationHeaderOperationFilter>();
        });

在 Swashbuckle 5 中,这是在 Startup.cs 中使用以下文件完成的。

// Register the Swagger generator, defining one or more Swagger documents
services.AddSwaggerGen(c =>
{
    c.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        BearerFormat = "JWT",
        Description = "JWT Authorization header using the Bearer scheme."
    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" }
            },
            new string[] {}
        }
    });
});