我想在 ASP.NET Core 2.0 中正确使用 DI,以便让我的自定义方法处理OnTokenValidated
在身份验证过程中验证 JWT 令牌后触发的事件。下面的解决方案有效,except在处理程序中我使用了一个注入的服务来命中MemoryCache
检查控制器中其他位置添加的缓存项(我已验证它们是否已添加并保留),并且当访问它时,缓存始终为空。我怀疑这是因为我的自定义处理程序对象是由不同的容器创建的(由于早期BuildServiceProvider()
调用?)并且正在利用一个单独的实例MemoryCache
(或类似)。
如果是这样的话,我想我不清楚如何正确添加和引用我的类和方法ConfigureServices()
在startup.cs中,以便它按预期工作。这是我所拥有的:
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
...
services.AddScoped<IJwtTokenValidatedHandler, JwtTokenValidatedHandler>();
// add other services
...
var sp = services.BuildServiceProvider();
services.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, bOptions =>
{
// Configure JwtBearerOptions
bOptions.Events = new JwtBearerEvents
{
OnTokenValidated = sp.GetService<JwtTokenValidatedHandler>().JwtTokenValidated
};
}
我的自定义处理程序类如下。这ValidateSessionAsync()
调用使用注入的AppSessionService
访问 MemoryCache 对象并确保缓存条目存在:
public class JwtTokenValidatedHandler : IJwtTokenValidatedHandler
{
AppSessionService _session;
public JwtTokenValidatedHandler(AppSessionService session)
{
_session = session;
}
public async Task JwtTokenValidated(TokenValidatedContext context)
{
// Add the access_token as a claim, as we may actually need it
var accessToken = context.SecurityToken as JwtSecurityToken;
if (Guid.TryParse(accessToken.Id, out Guid sessionId))
{
if (await _session.ValidateSessionAsync(sessionId))
{
return;
}
}
throw new SecurityTokenValidationException("Session not valid for provided token.");
}
}
如果定制OnTokenValidated
方法包含简单的逻辑,不需要注入服务,我将使用匿名函数内联它或在startup.cs中私有地声明它。如果可以的话,我更愿意修复这种方法,但我也愿意接受其他方法。
不要使用静态/单例事件,而是考虑子类化JwtBearerEvents
并使用JwtBearerOptions.EventsType
option:
public class CustomJwtBearerEvents : JwtBearerEvents
{
AppSessionService _session;
public CustomJwtBearerEvents(AppSessionService session)
{
_session = session;
}
public override async Task TokenValidated(TokenValidatedContext context)
{
// Add the access_token as a claim, as we may actually need it
var accessToken = context.SecurityToken as JwtSecurityToken;
if (Guid.TryParse(accessToken.Id, out Guid sessionId))
{
if (await _session.ValidateSessionAsync(sessionId))
{
return;
}
}
throw new SecurityTokenValidationException("Session not valid for provided token.");
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<CustomJwtBearerEvents>();
services.AddAuthentication()
.AddJwtBearer(options =>
{
options.EventsType = typeof(CustomJwtBearerEvents);
});
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)