在Swagger的Swashbuckler实现中添加授权属性过滤器

时间:2019-02-15 01:19:55

标签: swagger swashbuckle swashbuckle.examples

希望在Swashbuckle的Swagger实现中将AuthorizeFilterAttribute或AnonymousFilterAttribute添加到端点,以便在运行的以/ swagger结尾的webapi中生成的文档文件中的每个端点上使用哪个属性。这可能是屈辱吗?

我特别想添加一个大胆的标签,说明该端点为[匿名]或该端点正在使用[授权],并使它们的外观与摘要或备注文本不同。

我还希望能够为每个端点过滤出所有不同类型的限制过滤器属性,包括[NonAction],[Authorize]和[Anonymous],其中一个可能位于每个控制器的顶部端点。甚至可能最终在每个端点上除了这些属性之外还添加其他类型的FilterAttributes。

目前看来,只有HTTP方法,可以在当前实现中检索请求和响应对象,因此我无法找到有关此的明确信息。

由于这是Swagger的实现,这些.NET特定的属性过滤器是否不转换为Swashbuckle b / c,它们仅实现Swagger规范中的内容,而没有其他内容?

最后,他们对Swashbuckle的实现的.NET特定扩展是这样做的吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

对于将标签添加到不受保护的方法/动作的部分,您可以使用这样的操作过滤器

  public class UnprotectedOperationFilter : IOperationFilter
  {

    private bool HasAttribute(MethodInfo methodInfo, Type type, bool inherit)
    {
      // inhertit = true also checks inherited attributes
      var actionAttributes = methodInfo.GetCustomAttributes(inherit);
      var controllerAttributes = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(inherit);
      var actionAndControllerAttributes = actionAttributes.Union(controllerAttributes);

      return actionAndControllerAttributes.Any(attr => attr.GetType() == type);
    }

    public void Apply(Operation operation, OperationFilterContext context)
    {

      bool hasAuthorizeAttribute = HasAttribute(context.MethodInfo, typeof(AuthorizeAttribute), true);
      bool hasAnonymousAttribute = HasAttribute(context.MethodInfo, typeof(AllowAnonymousAttribute), true);

      // so far as I understood the action/operation is public/unprotected 
      // if there is no authorize or an allow anonymous (allow anonymous overrides all authorize)
      bool isAuthorized = hasAuthorizeAttribute && !hasAnonymousAttribute;

      if (!isAuthorized)
      {
        operation.Description = 
          "<p><bold>BIG BOLD LABEL indicating an UPROTECTED PUBLIC method</bold></p>" 
          + operation.Description;
      }

    }
  }

并添加

services.AddSwaggerGen(c => { c.OperationFilter<UnprotectedOperationFilter>();} );

我不明白您过滤掉不同属性的含义,但我希望上面的代码可以帮助您检查属性是否存在并执行您想做的事情。