.NET 8 Web API中Authorization请求头未生成到swagger.json的问题
项目信息
- 项目类型:ASP.NET Core Web API
- 框架版本:.NET 8.0
已排查操作
- 无错误输出
- 已确认
MyProject.csproj中启用了文档生成 - 清理并重建解决方案后,
MyProject.xml文件已生成,且包含请求头相关信息 - 访问
https://localhost:12345/swagger/v1/swagger.json,未找到Authorization请求头定义
相关代码
Program.cs
builder.Services.AddSwaggerGen(swagger => { swagger.SwaggerDoc("v1", new OpenApiInfo { Title = "MyProject", Version = "1.0.1" }); swagger.SwaggerDoc("v2", new OpenApiInfo { Title = "MyProject", Version = "2.0" }); // 引入XML注释文件 swagger.IncludeXmlComments(AppContext.BaseDirectory + Assembly.GetEntryAssembly().GetName().Name + ".xml", true); swagger.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new() { In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, Description = "Bearer Token", Name = "Authorization", BearerFormat = "JWT", Scheme = JwtBearerDefaults.AuthenticationScheme }); swagger.AddSecurityRequirement(new() { { new OpenApiSecurityScheme() { Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = JwtBearerDefaults.AuthenticationScheme } }, new string[]{ } } }); }); // 其他代码... if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(swagger => { swagger.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"); swagger.SwaggerEndpoint("/swagger/v2/swagger.json", "v2"); }); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseMiddleware<IdentityAuthenticationMiddleware>(); app.MapControllers(); app.Run();
控制器代码
/// <summary> /// UserInfo /// </summary> [ApiController] [Route("api/[controller]/[action]")] [Authorize(Roles = "User,Admin")] public class UserInfoController(HttpRequestModel httpRequestModel) : ControllerBase { private readonly HttpRequestModel _httpRequest = httpRequestModel; /// <summary> /// GetUserInfo /// </summary> /// <param name="authorization">Token</param> /// <returns>ResponseModel</returns> [HttpGet] public ResponseModel GetUserInfo([Required][FromHeader(Name = "Authorization")] string authorization) { using (UserInfoBll userInfoBll = new()) { return userInfoBll.GetUserInfoModel(_httpRequest.Token.UserId); } } }
解决方案
问题分析
当前代码同时通过Swagger安全定义和控制器参数两种方式处理Authorization头,但swagger.json未生成该字段,核心原因有两点:
- 控制器方法将
Authorization作为[FromHeader]参数接收,但Swagger的安全定义与显式参数存在优先级冲突,导致文档未正确生成; - 安全定义使用
SecuritySchemeType.ApiKey不符合JWT Bearer认证的规范,可能导致Swagger解析异常。
修复方案
方案1:修正Swagger安全定义规范
将安全定义的类型改为SecuritySchemeType.Http(符合JWT Bearer认证的标准),调整后的AddSecurityDefinition代码如下:
swagger.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "请输入格式为 `Bearer {Token}` 的认证令牌", Name = "Authorization", Type = SecuritySchemeType.Http, BearerFormat = "JWT", Scheme = "bearer" });
修改后清理并重建项目,Swagger会根据安全定义在swagger.json中生成对应的Authorization头要求,同时UI界面会显示标准的"Authorize"按钮。
方案2:移除控制器显式参数,通过HttpContext获取
如果不需要在方法参数中显式声明Authorization头,可以移除该参数,通过HttpContext直接读取请求头:
/// <summary> /// GetUserInfo /// </summary> /// <returns>ResponseModel</returns> [HttpGet] public ResponseModel GetUserInfo() { var authorizationHeader = HttpContext.Request.Headers["Authorization"].ToString(); // 后续业务逻辑保持不变 using (UserInfoBll userInfoBll = new()) { return userInfoBll.GetUserInfoModel(_httpRequest.Token.UserId); } }
这种方式下,Swagger会完全基于安全定义生成文档,swagger.json中会包含Authorization头的安全要求。
方案3:添加操作过滤器强制生成请求头
如果需要直接在接口参数列表中显示Authorization头,可以自定义Swagger操作过滤器,为标记[Authorize]的接口添加该参数:
- 在
AddSwaggerGen中注册过滤器:
swagger.OperationFilter<AddAuthorizationHeaderFilter>();
- 定义过滤器类:
public class AddAuthorizationHeaderFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { var requiresAuth = context.MethodInfo.DeclaringType.GetCustomAttributes<AuthorizeAttribute>().Any() || context.MethodInfo.GetCustomAttributes<AuthorizeAttribute>().Any(); if (requiresAuth) { operation.Parameters ??= new List<OpenApiParameter>(); operation.Parameters.Add(new OpenApiParameter { Name = "Authorization", In = ParameterLocation.Header, Description = "Bearer Token", Required = true, Schema = new OpenApiSchema { Type = "string" } }); } } }
该过滤器会遍历所有接口,为需要认证的接口强制添加Authorization请求头参数,确保swagger.json中能看到该字段。
内容的提问来源于stack exchange,提问作者Allen
相关产品推荐
相关产品推荐

