如何在AddOpenIdConnect的OnTokenValidated事件中注入可用服务?
AddOpenIdConnect认证成功回调中使用已注入服务的解决方案
OnTokenValidated回调的执行时机是在实际请求处理阶段,此时DI容器已经完全构建完成,你不需要在ConfigureServices阶段就把依赖注入到委托中,两种常用实现方案如下:
方案1:直接从请求上下文获取服务(最常用)
适合逻辑简单的场景,直接在回调中从当前请求绑定的服务容器中解析依赖,支持Singleton/Scoped/Transient全生命周期服务:
services.AddAuthentication(options => { options.DefaultScheme = "cookie"; }) .AddOpenIdConnect("oidc", options => { options.Authority = "https://localhost:5001"; options.Scope.Add("offline_access"); options.Events.OnTokenValidated = async n => { // 从当前请求的服务容器中获取需要的服务 var myOidcBusinessService = n.HttpContext.RequestServices.GetRequiredService<IMyOidcBusinessService>(); // 执行自定义业务逻辑 await myOidcBusinessService.HandleValidatedToken(n.Principal, n.SecurityToken); }; });
优点:写法简洁,无额外类定义成本,不会触发ASP0000生命周期不匹配警告。
方案2:自定义OpenIdConnectEvents实现类(适合复杂逻辑)
如果回调逻辑复杂、需要复用或者单元测试,可以自定义OpenIdConnectEvents的实现类,通过构造函数注入依赖:
- 定义自定义Events类
public class CustomOidcEvents : OpenIdConnectEvents { private readonly IMyOidcBusinessService _businessService; private readonly ILogger<CustomOidcEvents> _logger; // 构造函数直接注入任意生命周期的依赖 public CustomOidcEvents(IMyOidcBusinessService businessService, ILogger<CustomOidcEvents> logger) { _businessService = businessService; _logger = logger; } public override async Task TokenValidated(TokenValidatedContext context) { _logger.LogInformation("OIDC token validated, start processing business logic"); await _businessService.HandleValidatedToken(context.Principal, context.SecurityToken); // 保留默认逻辑执行 await base.TokenValidated(context); } }
- 注册服务和配置OIDC
// 注册业务服务和自定义Events类 services.AddScoped<IMyOidcBusinessService, MyOidcBusinessService>(); services.AddScoped<CustomOidcEvents>(); services.AddAuthentication(options => { options.DefaultScheme = "cookie"; }) .AddOpenIdConnect("oidc", options => { options.Authority = "https://localhost:5001"; options.Scope.Add("offline_access"); }) // 后期配置OIDC选项,从DI容器中获取自定义Events实例 .Configure<OpenIdConnectOptions>("oidc", (options, serviceProvider) => { options.Events = serviceProvider.GetRequiredService<CustomOidcEvents>(); });
优点:逻辑可复用、易维护、支持单元测试,适合需要处理多个OIDC事件的复杂场景。
内容的提问来源于stack exchange,提问作者Abhijeet
相关产品推荐
相关产品推荐

