I have 2 questions related to that:
1) I need to invalidate.AspNet.ApplicationCookie after Adding /
Removing some remote user to Role using Asp.Net Identity 2. I Tried to
use UpdateSecurityStamp, but since no password or username is
changed, SecurityStamp remains same. When I use ApplicationRoleManger
I can see that User roles are updated but in User.Identity Claims they
stay unchanged.
2) How does .AspNet.ApplicationCookie Validation work and how can I
access it?
I was trying to use this code, but with no effect
What is ASP.NET Identity's IUserSecurityStampStore<TUser> interface?
Update: This is my Cookie Auth setting:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromSeconds(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)),
OnApplyRedirect = ctx =>
{
if (!IsApiRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
I can see that user.GenerateUserIdentityAsync(manager) is hitted only on login.
Setting CookieAuthenticationOptions is not enough. When I created new ASP.NET MVC project in VS everything is working good and GenerateUserIdentityAsync() is hitted by each request (if validateInterval is 0). The only problem was that you have to register context per request:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
As I am using Winsdor Castle to create context per request, I deleted these lines from template.
In injected method in ApplicationUserManager.Create is set UserTokenProvider, which does the magic perharps.
Nowhere in documentation is anything about that, but finally it solves the problem.
If you are using your own IoC, you can resolve dependency this way (eg. using Castle Winsdor)
app.CreatePerOwinContext(() => IoCContainerManager.Container.Resolve<ApplicationDBContext>());
app.CreatePerOwinContext(() => IoCContainerManager.Container.Resolve<ApplicationUserManager>());
and register types this way:
container.Register(Component.For<ApplicationDBContext>().LifestylePerWebRequest());
container.Register(Component.For<ApplicationUserManager>().LifestylePerWebRequest());
If you want to change the security stamp after adding to a role use this:
UserManager.UpdateSecurityStampAsync(User.Id)
And don't set validateInterval
to TimeSpan.FromSeconds(0)
- this basically means database will be hit every on request. Set it to something like 10 minutes.
Just last night I've blogged about CookieAuthenticationProvider
and how it invalidates the cookie. Basically the cookie contains information about time it was created. If it is older than validateInterval
, then reach to database, get user record and compare security stamps in cookie and in the DB. If stamp not changed, issue a new cookie with new issue date. If stamps don't match, invalidate the cookie and log-out user.