.NET 4.6 OWIN应用不重启如何新增或更新Identity Provider配置
问题原因
OWIN的请求管道是应用启动时一次性通过IAppBuilder构建完成的,管道构建结束后再对IAppBuilder做任何修改都不会更新已生效的请求处理逻辑,这就是你重新调用AddOidcProviders方法不生效的根本原因。
可行解决方案
方案1:自定义动态OIDC认证中间件(推荐,无应用重启开销)
不要在启动时注册固定的OIDC提供商中间件,而是开发一个动态代理中间件,每次处理认证请求时实时拉取最新的IdP配置,动态生成对应OIDC中间件实例处理请求:
public class DynamicOidcMiddleware : OwinMiddleware { private readonly IAppBuilder _appBuilder; public DynamicOidcMiddleware(OwinMiddleware next, IAppBuilder appBuilder) : base(next) { _appBuilder = appBuilder; } public override async Task Invoke(IOwinContext context) { // 拦截OIDC认证请求:包括登录挑战、IdP回调请求,从请求参数/路径中提取对应IdP的唯一标识 if (TryMatchOidcRequest(context, out string providerId)) { // 实时从数据库读取最新的IdP配置,可加内存缓存降低数据库压力 var latestIdpConfig = await GetIdpConfigByIdFromDb(providerId); if (latestIdpConfig != null) { // 基于最新配置构建OIDC选项 var oidcOptions = BuildOidcOptions(latestIdpConfig); // 实例化OIDC中间件处理本次请求 var oidcMiddleware = new OpenIdConnectAuthenticationMiddleware(Next, _appBuilder, oidcOptions); await oidcMiddleware.Invoke(context); return; } } // 非OIDC请求直接走后续管道逻辑 await Next.Invoke(context); } }
启动时仅需注册这个动态中间件即可:
app.Use<DynamicOidcMiddleware>(app);
方案2:配置变更触发应用软重启(改造成本极低)
如果不想调整现有认证逻辑,可以监听数据库中IdP配置的变更事件,调用HttpRuntime.UnloadAppDomain()触发应用域软重启,这个操作不需要重启IIS应用池,重启速度极快,只要会话存储在分布式缓存而非进程内存中,用户几乎无感知。
注意事项
- 动态中间件方案中,每个IdP的回调路径需要配置唯一标识(比如
/signin-oidc/{providerId}),方便请求进来时快速匹配到对应的IdP配置 - 可对数据库拉取的IdP配置做短时间内存缓存,避免频繁查询数据库,配置更新时同步清理缓存即可
内容的提问来源于stack exchange,提问作者komsky
相关产品推荐
相关产品推荐

