简体   繁体   中英

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

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM