如何让FastAPI在动态注入认证方式时生成securitySchemas?
解决依赖注入下认证配置与SwaggerUI授权按钮显示问题
1. 提前初始化认证配置并注册为单例
既然OpenAPI生成在应用启动早期执行,延迟加载的依赖不会被求值,那就在启动阶段直接从配置读取参数,初始化好认证对象,再注册为单例服务。这样不管是路由还是Swagger模块,都能直接拿到已初始化的实例,不会出现配置未加载的情况。
示例代码(以ASP.NET Core为例):
// Program.cs var builder = WebApplication.CreateBuilder(args); // 从配置绑定认证模型 var authConfig = builder.Configuration.GetSection("AuthSettings").Get<AuthSettings>(); // 初始化认证方案 var jwtScheme = new AuthenticationScheme("DynamicJwt", "Dynamic JWT", typeof(JwtBearerHandler)) { Options = new JwtBearerOptions { Authority = authConfig.Authority, Audience = authConfig.Audience // 其他配置项 } }; // 注册为单例 builder.Services.AddSingleton<IAuthenticationSchemeProvider>(new AuthenticationSchemeProvider( new AuthenticationOptions(), new List<AuthenticationScheme> { jwtScheme } ));
2. 显式配置Swagger安全定义与要求
Swagger不会自动探测动态注入的认证配置,得手动在Swagger生成器里添加安全定义,再全局或针对路由添加安全要求,这样"Authorize"按钮才会显示,同时OpenAPI文档也能正确关联认证规则。
示例代码:
builder.Services.AddSwaggerGen(c => { // 添加JWT安全定义 c.AddSecurityDefinition("DynamicJwt", new OpenApiSecurityScheme { Type = SecuritySchemeType.Http, Scheme = "bearer", BearerFormat = "JWT", Description = "使用动态配置的JWT令牌认证" }); // 添加全局安全要求 c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "DynamicJwt" } }, Array.Empty<string>() } }); });
3. 路由显式指定认证方案
对于/dynamic和/dynamic-oidc这类路由,确保在[Authorize]属性里显式指定对应的认证方案名称,避免框架无法匹配到动态注入的认证规则。
示例代码:
[ApiController] [Route("dynamic")] [Authorize(AuthenticationSchemes = "DynamicJwt")] public class DynamicController : ControllerBase { // 路由方法 }
如果大部分路由都用同一个认证方案,也可以添加全局过滤器,省去每个控制器重复写的麻烦:
builder.Services.AddControllers(options => { var policy = new AuthorizationPolicyBuilder() .AddAuthenticationSchemes("DynamicJwt") .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); });
4. 强制触发认证服务初始化
有些依赖注入容器会延迟创建实例,导致OpenAPI生成时认证服务还没初始化。可以在应用启动后手动解析一次认证服务,触发初始化流程。
示例代码:
var app = builder.Build(); // 强制解析认证方案提供者,触发初始化 app.Services.GetRequiredService<IAuthenticationSchemeProvider>(); // 其他中间件配置... app.Run();
内容的提问来源于stack exchange,提问作者exhuma
相关产品推荐
相关产品推荐

