2016-08-11 128 views
5

我在ASP.NET Web API上使用Swashbuckle和Swagger。我试图找到一种方法来通过Swagger UI传递包含持票人令牌的授权标头。我一直在四处搜寻,但所有的答案似乎指向this链接。Swagger UI:传递自定义授权标头

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

这似乎是这样一个可笑的简单问题,但答案是什么?

回答

13

我们碰到了我们的项目同样的问题。我也想将标题参数添加到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.告诉扬鞭使用此OperationFilter 在SwaggerConfig,只是添加了操作过滤器应使用如下:

c.OperationFilter<AddAuthorizationHeader>(); 

希望这可以帮助你!

+0

看来,最新版本的Swashbuckle改变了操作类来移除参数过滤器类?有什么想法吗? –

+0

如果我创建过滤器,我所有的操作都要求它?我如何排除控制器操作不需要它? –

1

您可以通过不同的方式来完成,具体取决于您收集标头的方式,以及您希望代码处理所有事情,还是希望用户能够输入他们想要的标头Authorization

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

在我的情况下,我不得不通过用户的cookie向/token端点发送请求,以获得有效的Authorization令牌。所以我做了一些事情来达到这个目的。

首先在SwaggerConfig.cs我注释掉c.BasicAuth()得到基本身份验证方案到API的模式,我也注入其中,我插在为了抢Authorization令牌AJAX请求定制index.html页面,使用用户的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头。

下面我简单做一个AJAX调用我/token端点有效的cookie,得到Authorization令牌,并给它招摇着window.swaggerUi.api.clientAuthorizations.add()使用:

我删除了一些东西从AJAX打电话让它更简单,显然你的实现可能会有所不同,这取决于你如何收集你的令牌和东西,但这给你一个想法。如果您有任何具体问题或疑问,请告诉我。

*编辑:没有注意到你确实希望用户输入他们的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>(); 
... 
+0

感谢您的回答。我对你提到的第一件事感兴趣;即“当我第一次尝试这个时,我能够在用户可以输入授权标题的每个端点的参数字段区域中显示授权标题文本。你是怎么做的?正如问题中提到的,我希望用户输入授权标题,我不想让授权标题自动填入。 – fikkatra

+0

@fikkatra对不起,不知道我是如何错过的。请参阅编辑。 – hvaughan3

1

创建一个新的操作过滤器,实现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>(); 
     });