【发布时间】:2017-05-04 05:28:48
【问题描述】:
我有 jwt 身份验证:
var messageHandlers = new JwtMessageHandler(_serviceProvider);
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Events = new JwtBearerEvents
{
OnMessageReceived = messageHandlers.OnMessageReceived,
},
TokenValidationParameters = tokenValidationParameters
});
JwtMessageHandler 是我的自定义处理程序。在处理程序中,我必须对数据库进行一些查询,所以我通过 ServiceProvider 并解析我的用户服务:
public class JwtMessageHandler
{
private IUserService _userService;
public async Task OnMessageReceived(MessageReceivedContext arg)
{
//parsing header, get claims from token
...
_userService = (IUserService)arg.HttpContext.RequestServices.GetService(typeof(IUserService));
var isRoleChanged = await _userService.IsRoleChanged(tokenObject.Subject, rolesFromToken);
if (isRoleChanged)
{
GenerateBadResponse(arg);
return;
}
var canLogin = await _userService.CanLogin(tokenObject.Subject);
if (!canLogin)
{
GenerateBadResponse(arg);
return;
}
}
}
在服务中我进行查询:
...
var user = await _userManager.FindByEmailAsync(email);
var currentRoles = await _userManager.GetRolesAsync(user);
..
每个请求都会调用OnMessageReceived。
当我在页面上有一个对服务器的请求时,或者我在做某事之前等待一两秒钟,一切正常。但是,我有几个页面同时向服务器发出 2-3 个请求。而且,在这种情况下,我会收到以下错误:
连接没有关闭。连接的当前状态是正在连接
我理解多线程的问题。 JwtMessageHandler 在应用程序启动时创建一次。所以,我把这条线:
_userService = (IUserService)_serviceProvider.GetService(typeof(IUserService));
inside 方法,在它位于构造函数之前。但是,它没有帮助。另外,我尝试在方法结束时将 null 设置为 _userService。
这种情况下如何正确使用?
【问题讨论】:
-
您如何在
Startup中注册IUserService?单例、作用域、过渡? -
@Dmitry 它的范围。
services.AddScoped<IUserService, UserService>(); -
而您尝试使用在“当前”范围之外创建的
serviceProvider来获取范围服务......非常危险。查看内部MessageReceivedContext- 那里应该有其他ServiceProvider,直接或通过HttpContext...从那里询问您的服务。 -
@Dmitry 刚试过。
_userService = (IUserService)arg.HttpContext.RequestServices.GetService(typeof(IUserService));。而且,无论如何,我得到了错误。主要问题是捕获错误,我随机收到此错误。我可以工作一段时间,然后只有重新启动服务器才有帮助。 -
对您的应用程序的每个请求都会创建单独的 HttpRequest 和单独的范围以及单独的
IUserService实例,它们应该使用单独的DbContext实例。您的 DbContext 注册是否“正常”?你确定你在等待OnMessageReceived本身吗?可能是请求处理链中的某些内容在您仍在执行IsRoleChanged时对数据库进行查询?
标签: c# asp.net entity-framework asp.net-core entity-framework-core