I have jwt auth:
var messageHandlers = new JwtMessageHandler(_serviceProvider);
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    Events = new JwtBearerEvents
    {
        OnMessageReceived = messageHandlers.OnMessageReceived,
    },
    TokenValidationParameters = tokenValidationParameters
});
The JwtMessageHandler is my custom handler. In the handler I have to make some queries to database, so I pass ServiceProvider and resolve my user service:
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;
            }
        }    
}
In the service I make queries:
...
 var user = await _userManager.FindByEmailAsync(email);
 var currentRoles = await _userManager.GetRolesAsync(user);
..
The OnMessageReceived is called for every request.
When I have one request on page to the server or I wait one-two seconds before doing something all works fine. But, I have several pages where I make 2-3 simultaneous requests to the server. And, in this case I get error about:
The connection was not closed. The connection's current state is connecting
I understand that problem with multithreading. The JwtMessageHandler is created once when application is started. So, I put the line:
_userService = (IUserService)_serviceProvider.GetService(typeof(IUserService)); 
inside method, before it was located in the constructor. But, It didn't help. Also, I tried to set null to _userService in the end of my method.
How to correctly use in this case?
Trying to use a connection that is already "connecting" - clear sign of some race condition.
IUserService is registered with "scope" lifetime, and all it dependencies (userManager, dbContext) tooIServiceProvider you obtained during app startup for scope-bases services resolution - it is NOT related to current request scope and return instances from "some other universe". Use HttpContext.RequestServices for service resolution.JwtMessageHandler instance is one/single per app. So don't use it's property for storing _userService (remove private IUserService _userService). Instead, use local variable inside OnMessageReceived (var _userService = ...).You already checked (1), (2) and (3). I think (4) is the last one you need to fix your bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With