You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swashbuckle的IDocumentFilter类中获取请求头?

关于IDocumentFilter中检查请求头的问题

我的代码实现

public class ShowDocumentationFilter : IDocumentFilter
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class ShowDocumentationAttribute : Attribute
    {
    }

    void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        //如果请求不包含请求头,则执行以下操作:
        foreach (ApiDescription apiDescription in apiExplorer.ApiDescriptions)
        {
            if ((apiDescription.RelativePathSansQueryString().StartsWith("api/System/"))
                || (apiDescription.RelativePath.StartsWith("api/Internal/"))
                || (apiDescription.Route.RouteTemplate.StartsWith("api/OtherStuff/"))
                )
            {
                swaggerDoc.paths.Remove("/" + apiDescription.Route.RouteTemplate.TrimEnd('/'));
            }
        }
    }
}

问题

我希望将上述逻辑应用到我的端点上,但能否在这个ShowDocumentationFilter类中检查访问端点的请求是否包含特定请求头?


解答

首先明确:IDocumentFilter的Apply方法是在生成Swagger文档时执行的,并非处理实际接口请求的阶段,所以这个方法里没法直接获取当前的HTTP请求上下文,自然也没法直接检查请求头。

如果要实现「根据请求头决定是否显示指定Swagger文档」的需求,可以通过以下方式实现:

方案一:注入IHttpContextAccessor获取请求上下文

通过依赖注入拿到当前请求的上下文,就能判断请求头是否存在:

  1. 先在项目的启动配置(Startup.cs 或 Program.cs)中注册IHttpContextAccessor:
    services.AddHttpContextAccessor();
    
  2. 修改过滤器类,注入IHttpContextAccessor并添加请求头检查逻辑:
    public class ShowDocumentationFilter : IDocumentFilter
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        // 通过构造函数注入请求上下文访问器
        public ShowDocumentationFilter(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
    
        [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
        public class ShowDocumentationAttribute : Attribute
        {
        }
    
        void IDocumentFilter.Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
        {
            var httpContext = _httpContextAccessor.HttpContext;
            // 检查是否存在目标请求头,这里以"X-Allow-Internal-Docs"为例
            var hasRequiredHeader = httpContext?.Request.Headers.ContainsKey("X-Allow-Internal-Docs") ?? false;
    
            // 仅当没有指定请求头时,才移除指定路径的文档
            if (!hasRequiredHeader)
            {
                foreach (ApiDescription apiDescription in apiExplorer.ApiDescriptions)
                {
                    var isInternalPath = apiDescription.RelativePathSansQueryString().StartsWith("api/System/")
                                        || apiDescription.RelativePath.StartsWith("api/Internal/")
                                        || apiDescription.Route.RouteTemplate.StartsWith("api/OtherStuff/");
    
                    if (isInternalPath)
                    {
                        var pathKey = "/" + apiDescription.Route.RouteTemplate.TrimEnd('/');
                        // 先判断键是否存在,避免抛出异常
                        if (swaggerDoc.paths.ContainsKey(pathKey))
                        {
                            swaggerDoc.paths.Remove(pathKey);
                        }
                    }
                }
            }
        }
    }
    
    这种方式会在每次请求Swagger文档时,根据当前请求的头信息动态生成文档内容。

方案二:使用中间件全局控制

如果需要更全局的权限控制,可以编写一个中间件,在请求Swagger文档接口时先检查请求头,不符合条件的直接返回禁止访问(如403状态码),不过这种方式的灵活性不如过滤器高。


内容的提问来源于stack exchange,提问作者Joe Defill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:54:23