且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ASP身份2.0:重生身份

更新时间:2023-12-05 11:28:28

如果您尝试添加新角色已经登录的用户,您需要注册用户了。然后创建与新身份新角色和标志用户新的身份。这是更新的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.