使用在 startup.cs 中分配的委托处理 OnTokenValidated 时出现问题
Posted
技术标签:
【中文标题】使用在 startup.cs 中分配的委托处理 OnTokenValidated 时出现问题【英文标题】:Problems handling OnTokenValidated with a delegate assigned in startup.cs 【发布时间】:2018-03-30 19:55:47 【问题描述】:我想在 ASP.NET Core 2.0 中正确使用 DI,以便让我的自定义方法处理在身份验证期间验证 JWT 令牌后触发的 OnTokenValidated
事件。下面的解决方案有效,除了在处理程序中我使用了一个注入服务,该服务命中MemoryCache
来检查在控制器中其他地方添加的缓存项(我已经验证它们已添加并持久化) ,并且当它被访问时,缓存总是空的。我怀疑这是因为我的自定义处理程序对象是由不同的容器创建的(由于早期的BuildServiceProvider()
调用?)并且正在使用MemoryCache
(或类似的)的单独实例。
如果是这种情况,我想我不清楚如何在 startup.cs 中的ConfigureServices()
中正确添加和引用我的类和方法,以便它按预期工作。这是我所拥有的:
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 中私下声明它。如果可以的话,我更愿意修复这种方法,但我愿意接受其他方法。
【问题讨论】:
【参考方案1】:考虑继承JwtBearerEvents
并使用JwtBearerOptions.EventsType
选项,而不是使用静态/单例事件:
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);
);
【讨论】:
这也将阻止设置为 [AllowAnonymous] 的 API。任何想法如何处理?以上是关于使用在 startup.cs 中分配的委托处理 OnTokenValidated 时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
Firebase:保留在observeSingleEvent中分配的值[重复]