通过 DI 解决身份验证事件处理程序的依赖关系

Fra*_*ank 4 c# dependency-injection asp.net-core

我使用 JWT 不记名令牌来保护我的 ASP.NET Core 2.1 Web API。在 期间ConfigureServices,我设置了身份验证,并JwtBeaererEvents通过选项绑定对象以进行额外处理。我希望这个对象成为 DI 容器的一部分,但我不确定如何做到这一点。现在,我必须创建实例并通过构造函数(反模式)传递它。但这将创建一个鸡和一个蛋的场景:

/* HACK */
var sp = services.BuildServiceProvider();

services.AddAuthentication(opts =>
{
    opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opts =>
{                
    opts.Audience = "https://foobar.com/FooAPI";
    opts.Authority = Constants.AuthEndpointPrefix + "common/";
    opts.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false };

    /* I would like JwtBearerEvents to be part of the 
       DI container and request the Logger and AppInsights 
       Dependency through the ctor 
    */
    opts.Events = new 
       JwtBearerEvents(
          LoggerFactory.CreateLogger<JwtBearerEvents>(),
          sp.GetService<TelemetryClient>() 
       );  
    });     
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 10

ASP.NET Core 2 中的身份验证系统使用身份验证方案选项的EventsType属性在本机支持此功能:

services.AddTransient<MyJwtBearerEvents>();
services.AddAuthentication()
    .AddJwtBearer(options =>
    {
        options.EventsType = typeof(MyJwtBearerEvents);
    });
Run Code Online (Sandbox Code Playgroud)

如果设置了此属性,则在请求开始时初始化身份验证方案时将解析事件实例。

除此之外,请注意,您还可以访问HttpContext作为事件上下文的一部分传递的实例,并使用服务定位器模式来解析事件处理程序内的服务。虽然使用服务定位器通常不是最好的主意,但在这种情况下,如果您只需要特定事件类型的一些依赖项,它可以为您提供更多的灵活性。