我有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));
在方法中,我曾尝试过将某些代码移到构造函数中,但没有效果。同时,在方法结束后,我还尝试将_userService
设置为null。
请问在这种情况下应该如何正确使用?
serviceProvider
来获取作用域服务,则非常危险。请查看MessageReceivedContext
内部 - 那里应该有其他ServiceProvider
,直接或通过HttpContext...从那里请求您的服务。 - DmitryIUserService
实例,这些实例应该使用单独的DbContext
实例。您的DbContext
注册是否“通常”?您确定您在等待OnMessageReceived
本身吗?也许在请求处理链中有些东西在您执行IsRoleChanged
时查询了数据库? - Dmitry_userService
变量存在竞态条件。请删除private IUserService _userService
,并在方法内部使用var _userService =...
。 - Dmitry