ASP身份2.0:重生身份 [英] ASP Identity 2.0: Regenerate Identity
问题描述
我有麻烦ASP身份来刷新存储在随需应变的cookie其身份。
I am having trouble getting ASP Identity to refresh its Identity stored in a cookie on demand.
在 Startup.Auth.cs
文件中的cookie设置为再生如下:
In the Startup.Auth.cs
file the cookie is set to regenerate as follows:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<QuizSparkUserManager, QuizSparkUser, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: ((manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)),
getUserIdCallback: ((claimsIdentity) => int.Parse(claimsIdentity.GetUserId())))
}
});
不过,我不能工作,如何刷新 User.Identity
在code,即内容强制身份的cookie的刷新,当我需要它来刷新
However I cannot work out how to refresh the contents on User.Identity
in code, i.e. force a refresh of the identity cookie when I need it to refresh.
我希望能够以编程方式使用再生身份的回调,这可能吗?
I want to be able to use the regenerate identity callback programmatically, is this possible?
我的问题是类似这样的:<一href=\"http://stackoverflow.com/questions/25546333/how-to-invalidate-aspnet-applicationcookie-after-adding-user-to-role-using-asp\">How使用Asp.Net身份2将用户添加到角色后无效.AspNet.ApplicationCookie?
My problem is similar to this one : How to invalidate .AspNet.ApplicationCookie after Adding user to Role using Asp.Net Identity 2?
不过,我想刷新,而不是无效的cookie。
However I want to refresh rather than invalidate the cookie.
修改
看链接的问题后,我试图以下(不完整的错误处理):
After looking at the linked question I attempted the following (without full error handling):
IOwinContext context = Request.GetOwinContext();
QuizSparkSignInManager manager = context.Get<QuizSparkSignInManager>();
ClaimsIdentity newIdentity = manager.CreateUserIdentity(manager.UserManager.FindById(User.Identity.GetUserId<int>()));
AuthenticateResult authenticationContext =
await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie);
if (authenticationContext != null)
{
context.Authentication.AuthenticationResponseGrant = new AuthenticationResponseGrant(
newIdentity, authenticationContext.Properties);
}
bool first2 = User.IsInRole("Turtle");
EDIT2:但是用户仍然没有出现刷新。在页面重载他们似乎刷新,我是正确的思维,这是因为User.Identity cookie是请求的一部分,不能在code改变?
However the User still does not appear to refresh. On page reload they do seem to refresh, am I right in thinking this is because User.Identity cookie is part of the request and cannot be changed in code?
推荐答案
如果您尝试添加新角色已经登录的用户,您需要注册用户了。然后创建与新身份新角色和标志用户新的身份。这是更新的cookie的唯一途径。
If you are trying to add new role to already logged-in user, you need to sign user out. Then create new identity with new role and sign user in with the new identity. That's the only way to update the cookie.
要检查是否已经改变了用户属性是你已经在使用回调最好的地方: CookieAuthenticationProvider.OnValidateIdentity
。事情是这样的。
Best place to check if user properties have changed are in callback you already use: CookieAuthenticationProvider.OnValidateIdentity
. Something like this.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
// other stuff
Provider = new CookieAuthenticationProvider
{
// this function is executed every http request and executed very early in the pipeline
// and here you have access to cookie properties and other low-level stuff.
// makes sense to have the invalidation here
OnValidateIdentity = async context =>
{
// invalidate user cookie if user's security stamp have changed
var invalidateBySecirityStamp = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager));
await invalidateBySecirityStamp.Invoke(context);
if (context.Identity == null || !context.Identity.IsAuthenticated)
{
return;
}
if(/*Need to update cookie*/)
{
// get user manager. It must be registered with OWIN
var userManager = context.OwinContext.GetUserManager<UserManager>();
var username = context.Identity.Name;
// get new user identity with updated properties
var updatedUser = await userManager.FindByNameAsync(username);
// updated identity from the new data in the user object
var newIdentity = updatedUser.GenerateUserIdentityAsync(manager);
// kill old cookie
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
// sign in again
var authenticationProperties = new AuthenticationProperties() { IsPersistent = context.Properties.IsPersistent };
context.OwinContext.Authentication.SignIn(authenticationProperties, newIdentity);
}
}
}
});
免责声明 - 从未测试过,甚至没有试图编译
Disclaimer - never tested it, not even tried to compile it.
也可以看到我的其他答案参考 - pretty多同一块code的,但不同的目标。
Also can see my other answer for reference - pretty much the same piece of code, but different goal.
UPD:
关于这个问题的另一部分 - 如何检测一个角色的变化:结果
我能想到的办法 - 对用户记录另一个GUID。类似 SecurityStamp
,但不使用框架。说它 MySecurityStamp
。在登录添加 MySecurityStamp
的值到cookie作为索赔。在每次请求中的cookie来在数据库中的值进行比较 MySecurityStamp
的价值。如果值不同 - 时间以再生的身份。而在每一个新的角色添加/删除修改 MySecurityStamp
在数据库中的用户。这将覆盖所有的浏览器的所有会话。
UPD:
Regarding another part of the question - how to detect a role change:
I can think of a way - have another GUID on a user record. Similar to SecurityStamp
, but not used by the framework. Call it MySecurityStamp
. On sign-in add value of MySecurityStamp
to the cookie as a claim. On every request compare value of MySecurityStamp
in the cookie to the value in the database. If values are different - time to regenerate the identity. And on every new role added/removed modify MySecurityStamp
for the user in the database. This will cover all the sessions in all the browsers.
这篇关于ASP身份2.0:重生身份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!