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

.NET 6自定义认证中间件拦截Swashbuckle Swagger页面如何修复

问题描述

.NET 6 Minimal API 项目使用默认配置集成 Swagger/Swashbuckle 时功能正常,添加自定义 ApiKey 认证中间件后访问异常:
认证中间件默认对所有请求执行ApiKey校验逻辑,包含/swagger/index.html在内的Swagger相关页面、静态资源请求默认不会携带ApiKey请求头,会直接触发校验分支返回400错误,导致Swagger页面无法加载。

原有问题代码如下:
Program.cs 中间件注册代码:

app.UseMiddleware<Auth>();

Auth.cs 中间件逻辑代码:

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
    if (!context.Request.Headers.ContainsKey("ApiKey"))
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("No ApiKey provided in headers");
    }

    if (!Guid.TryParse(context.Request.Headers["ApiKey"], out var apiKey))
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("Unable to parse the ApiKey");
    }

    try
    {
        /* Look in DB for API Key yada yada yada */
    }
    catch
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        await context.Response.WriteAsync("Unauthorized");
    }

    await next(context);
}
修复方案

原有代码存在两个核心问题:一是没有对Swagger相关路径做白名单放行,二是校验失败分支没有做请求短路,写入错误响应后依然会执行后续逻辑,可能出现多次写入响应的异常。按以下步骤修复即可:

  • 在认证逻辑最开头添加Swagger路径白名单判断,所有匹配Swagger前缀的请求直接跳过认证,传递到后续中间件处理,默认Swagger路径前缀为/swagger,判断时注意忽略大小写。
  • 所有校验不通过的分支,在写入错误响应后直接return终止当前请求逻辑,不要继续执行后续校验和管道调用,避免响应冲突。

修复后的Auth.cs代码如下:

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
    // 放行所有Swagger相关请求,跳过ApiKey校验
    if (context.Request.Path.StartsWithSegments("/swagger", StringComparison.OrdinalIgnoreCase))
    {
        await next(context);
        return;
    }

    if (!context.Request.Headers.ContainsKey("ApiKey"))
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("No ApiKey provided in headers");
        return;
    }

    if (!Guid.TryParse(context.Request.Headers["ApiKey"], out var apiKey))
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("Unable to parse the ApiKey");
        return;
    }

    try
    {
        /* 数据库校验ApiKey逻辑 */
    }
    catch
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        await context.Response.WriteAsync("Unauthorized");
        return;
    }

    await next(context);
}

如果你自定义过Swagger的路由前缀,把代码中判断路径的/swagger替换为实际配置的前缀即可。如果需要在Swagger页面调试接口时自动携带ApiKey,可以额外给Swashbuckle配置全局ApiKey请求头参数,不影响Swagger页面本身的加载逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:33:16