使用Swashbuckle时,如何为Swagger单独移除Bearer Token认证且不影响其他客户端?
嘿,我来帮你搞定这个需求——让Swagger不用管Bearer Token认证,但Postman这类客户端调用API时授权依然正常生效。根据你用Swashbuckle的情况,有两种方案可以选,看哪种更贴合你的预期:
方案1:让Swagger文档彻底去掉Bearer Token的授权提示
这种方式很直接:Swagger UI里不会再显示Token输入框,接口文档也不会标注需要认证,但API本身的授权逻辑完全保留,Postman调用受保护接口时还是得带有效Token。
具体操作步骤
修改Swagger生成配置
找到你项目里配置AddSwaggerGen的地方(一般在Program.cs或者Startup.cs),把之前添加Bearer Token安全定义和安全要求的代码删掉就行。
之前的代码大概是这样的:services.AddSwaggerGen(c => { // 原来的Bearer Token安全定义 c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "Bearer" }); // 原来的安全要求 c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] {} } }); });把这两段删掉,Swagger就不会再提Bearer Token的事了。
保留API的授权中间件
别碰UseAuthentication()和UseAuthorization()这两行代码,这样Postman这类客户端调用时,授权逻辑还是正常工作的,没带Token的话照样返回401。
方案2:让Swagger调用API时直接跳过授权验证
如果你想要的是Swagger里点调用按钮就能直接访问接口,不用输Token,但Postman调用必须带Token,那得通过判断请求来源来跳过授权。
具体操作步骤
可选:保留Swagger的授权提示
如果你还想让Swagger UI显示Token输入框(只是实际调用时不用验证),就保留AddSwaggerGen里的安全定义代码;如果不想显示,就按方案1删掉。添加自定义逻辑跳过Swagger请求的授权
这里有两种方式:方式A:用自定义授权策略
先注册自定义的授权需求和处理程序:
services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddRequirements(new SkipSwaggerAuthorizationRequirement()) .Build(); }); services.AddSingleton<IAuthorizationHandler, SkipSwaggerAuthorizationHandler>();然后创建对应的需求和处理类:
public class SkipSwaggerAuthorizationRequirement : IAuthorizationRequirement { } public class SkipSwaggerAuthorizationHandler : AuthorizationHandler<SkipSwaggerAuthorizationRequirement> { private readonly IHttpContextAccessor _httpContextAccessor; public SkipSwaggerAuthorizationHandler(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SkipSwaggerAuthorizationRequirement requirement) { var httpContext = _httpContextAccessor.HttpContext; // 检测是不是Swagger相关的请求路径 if (httpContext.Request.Path.StartsWithSegments("/swagger") || httpContext.Request.Path.StartsWithSegments("/swagger/v1/swagger.json")) { context.Succeed(requirement); return Task.CompletedTask; } // 其他请求正常走授权验证 if (context.User.Identity.IsAuthenticated) { context.Succeed(requirement); } return Task.CompletedTask; } }方式B:用自定义中间件快速跳过
在
Program.cs里,UseAuthentication()和UseAuthorization()之前加一段中间件:app.Use(async (context, next) => { // 判断是不是Swagger的请求 if (context.Request.Path.StartsWithSegments("/swagger")) { // 直接跳过授权,执行后续逻辑 await next(); return; } // 其他请求正常走授权流程 await next(); }); app.UseAuthentication(); app.UseAuthorization();注意中间件的顺序一定要对,放在授权中间件前面才行。
总结一下
- 要是你只是不想Swagger显示Token输入框,API正常验证其他客户端,选方案1就够了,简单直接。
- 要是你想让Swagger调用接口时完全不用管Token,其他客户端必须验证,就选方案2。
内容的提问来源于stack exchange,提问作者Ramya Ravi

