如何在Swagger中有选择地将OperationFilter添加到API端点?

5kgi1eie  于 2022-12-13  发布在  其他
关注(0)|答案(2)|浏览(169)

我有以下IOperationFilter类,它实现了API应用程序中某些端点所需的身份验证头:

public class AuthenticationHeadersFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Parameters == null)
            operation.Parameters = new List<OpenApiParameter>();

        operation.Parameters.Add(new OpenApiParameter
            {
                Name = "AccountName",
                In = ParameterLocation.Header,
                Required = true
            });

        operation.Parameters.Add(new OpenApiParameter
            {
                Name = "ApiKey",
                In = ParameterLocation.Header,
                Required = true
            });
    }
}

通过在Startup.csConfigureServices方法中执行以下操作,将上述内容添加到应用程序的Swagger UI中:

services.AddSwaggerGen(c =>
{
    // ...
    // other Swagger configurations
    // ... 
    c.OperationFilter<AuthenticationHeadersFilter>();
});

这很好用,但是我现在也有一些端点,我希望由Swagger记录/显示,但是应该是完全公开的,而不需要用户在他们的API请求中提供AccountNameApiKey作为头文件。我该如何完成呢?
我找到了this Stack Overflow answer,但不确定它是否适合我在这里的用途。我无法找到任何关于OperationFilterContext类的有用文档。
任何帮助都是非常感谢的。

ql3eal8s

ql3eal8s1#

可能的解决方案是使用如下属性

using System;

namespace some.namespace
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class SkipAuthenticationHeadersAttribute : Attribute
    {
    }
}

并在swagger AuthenticationHeadersFilter中使用它,如下所示:

using System.Linq;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace some.namespace
{
    /// <summary>
    /// https://alexdunn.org/2018/06/29/adding-a-required-http-header-to-your-swagger-ui-with-swashbuckle/.
    /// </summary>
    public class AuthenticationHeadersFilter : IOperationFilter
    {
        /// <summary>
        /// Swagger: Creates new required http header.
        /// </summary>
        /// <param name="operation"> Open Api Operation.</param>
        /// <param name="context">Operation Filter Context.</param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var globalAttributes = context.ApiDescription.ActionDescriptor.FilterDescriptors.Select(p => p.Filter);
            var controllerAttributes = context.MethodInfo?.DeclaringType?.GetCustomAttributes(true);
            var methodAttributes = context.MethodInfo?.GetCustomAttributes(true);
            var produceAttributes = globalAttributes
                .Union(controllerAttributes ?? throw new InvalidOperationException())
                .Union(methodAttributes)
                .OfType<SkipAuthenticationHeadersAttribute>()
                .ToList();

            if (produceAttributes.Count != 0)
            {
                return;
            }

            if (operation.Parameters == null)
            {
                operation.Parameters = new List<OpenApiParameter>();
            }

            operation.Parameters.Add(new OpenApiParameter
            {
               Name = "AccountName",
               In = ParameterLocation.Header,
               Required = true
            });

            operation.Parameters.Add(new OpenApiParameter
            {
               Name = "ApiKey",
               In = ParameterLocation.Header,
               Required = true
            });
        }
    }
}

因此,当您将属性添加到控制器操作时,该操作将被过滤掉。

5ktev3wc

5ktev3wc2#

SwaggerOperationFilter属性特别适用于这种情况。
您需要安装并启用软件包Swashbuckle.AspNetCore.Annotations

// Startup.cs
services.AddSwaggerGen(c =>
{
    ...
    c.EnableAnnotations();
};

然后可以像[SwaggerOperationFilter(typeof(YourFilterClass))]一样使用它,而不是c.OperationFilter<YourFilterClass>();

相关问题