Swagger UI:传递自定义授权标头

时间:2016-08-11 21:10:33

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

我在ASP.NET Web API上使用Swashbuckle和Swagger。我正在尝试通过Swagger UI找到一种传递包含Bearer令牌的Authorization标头的方法。我一直在搜索,但所有答案似乎都指向this链接。

但是,这假定标头的内容是预先知道的。我真的需要一种方法来改变Swagger UI中的标题(在点击'试一试!'按钮之前),因为Bearer标记每小时都会到期。与Postman允许您添加标题的方式类似。

这似乎是一个如此荒谬的简单问题,但答案是什么?

4 个答案:

答案 0 :(得分:21)

我们在项目中遇到了同样的问题。我还想将标头参数添加到Swagger UI网站。这就是我们这样做的方式:

<强> 1。定义OperationFilter类 每次构建Swagger时,都会对每个API操作执行OperationFilters。根据您的代码,将根据您的过滤器检查操作。在此示例中,我们在每个操作上都需要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>();

希望这会帮助你!

答案 1 :(得分:4)

创建一个实现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>();
        });

答案 2 :(得分:2)

您可以采用不同的方式执行此操作,具体取决于您收集Authorization标头的方式以及您是否希望代码处理所有内容,或者您​​是否希望用户能够输入Authorization标题他们想要。

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

在我的情况下,我必须使用用户的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标题。

下面我只使用有效的Cookie向我的/token端点发出AJAX调用,获取Authorization令牌,然后将其招摇以便与window.swaggerUi.api.clientAuthorizations.add()一起使用:

...

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标题。在这种情况下,这很容易。我使用了this帖子。只需创建以下类来完成工作:

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

然后将课程添加到我的SwaggerConfig,如下所示:

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

答案 3 :(得分:1)

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