Asp.Net 5 / Identity 3: Caching of Claims in the IdentityDbContext implementation

asp.net asp.net-core asp.net-identity-3 c# entity-framework-core

Question

While looking for a way to be able to assign and revoke roles via an admin controller for users other than the one making a request, I've implemented a custom IAuthorizeFilter that checks if Guid tag, stored as a Claim, matches to a value in the Entity Framework 7 Code First Identity table for UserClaims.

Essentials, it's this code:

public class RefreshUserClaimsFilterAttribute : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext context)
    {
        var User = context.HttpContext.User;
        var dbContext = context.HttpContext.ApplicationServices.GetRequiredService<ApplicationDbContext>();
        var stampFromClaims = User.Claims.FirstOrDefault(Claim => Claim.Type == "ClaimsStamp")?.Value;
        var stampFromDb = dbContext.UserClaims.Where(UserClaim => UserClaim.UserId == User.GetUserId()).ToList().FirstOrDefault(UserClaim => UserClaim.ClaimType == "ClaimsStamp")?.ClaimValue; 
        // Update claims via RefreshSignIn if necessary
    }
}

I'm having the problem at the line where I'm assigning var stampFromDb, it could be much more readable in the following way:

var stampFromDb = dbContext.UserClaims.FirstOrDefault(UserClaim => UserClaim.UserId == User.GetUserId() && UserClaim.ClaimType == "ClaimsStamp")?.ClaimValue;

That, however, gives me cached (the same values as the actual claims from User.Identity) results and I could not find any documentation on this. My best guess is that the error is somewhere on my side, but I've never encountered such a problem before. This is the first time I'm using Asp.Net 5 and EF7. I'm using the default connection (LocalDB) to SQL Server 12.0.2000.

Is this a feature and, if yes, can it be turned off or did I make a mistake somewhere?

Accepted Answer

The issue was caused due to there being two different ways to create a service via dependency injection: The sample code in my question used

var dbContext = context.HttpContext.ApplicationServices.GetRequiredService<ApplicationDbContext>();

where it should use

var dbContext = context.HttpContext.RequestServices.GetRequiredService<ApplicationDbContext>();

The difference here is between ApplicationServices and RequestServices. It looks like the ApplicationServices injector does have an instance of the database context somewhere which has had the DbSet filled earlier and therefore returning cached data instead of doing a database query.



Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why