I'm using Asp.NET Identity 2.1.0
and I store a list of Accounts
that a User
has access to, as Claims. The ClaimsIdentity
is generated when the User
signs in:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add Claims concerning Account
userIdentity.AddClaim(new Claim("AccountList", SerializedListOfAccounts));
return userIdentity;
}
Let's say that an Administrator revokes User A
's access to a specific Account. How can I force User A
to regenerate its ClaimsIdentity
? Remember that it isn't in the context of User A
. And I don't want to wait until the cookie has expired (and a new ClaimsIdentity
is automatically generated.
Is it possible? Isn't there a way to tell the server to regard User A
's cookie as invalid and force it to regenerate it?
The reason I want this behaviour is to create a custom AuthorizeAttribute
that I can put on my controllers that checks the Claims
to see if a User
has access or not, to avoid an extra round trip to the database.
You can not store their claims on cookie, but apply them on every request to the identity early in the pipeline. You'll have to hack Startup.Auth.cs
to do that. I'm doing just that here.
And here is the gist you can work with:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
Provider = GetMyCookieAuthenticationProvider(),
// other configurations
});
// other usual code
}
private static CookieAuthenticationProvider GetMyCookieAuthenticationProvider()
{
var cookieAuthenticationProvider = new CookieAuthenticationProvider();
cookieAuthenticationProvider.OnValidateIdentity = async context =>
{
// execute default cookie validation function
var cookieValidatorFunc = SecurityStampValidator.OnValidateIdentity<UserManager, ApplicationUser>(
TimeSpan.FromMinutes(10),
(manager, user) =>
{
var identity = manager.GenerateUserIdentityAsync(user);
return identity;
});
await cookieValidatorFunc.Invoke(context);
// sanity checks
if (context.Identity == null || !context.Identity.IsAuthenticated)
{
return;
}
// get your claim from your DB or other source
context.Identity.AddClaims(newClaim);
};
return cookieAuthenticationProvider;
}
}
The drawbacks that you need to apply claims on every request and this might be not very performant. But right amount of caching in the right place will help. Also this piece of code is not the easiest place to work, as it is very early in the pipeline and you need to manager yourself DbContext
and other dependencies.
The upsides are that the claims are applied right away to every user's request and you get immediate change of permissions without having to re-login.
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