ASP 身份 2.0:重新生成身份 [英] ASP Identity 2.0: Regenerate Identity

查看:27
本文介绍了ASP 身份 2.0:重新生成身份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法让 ASP 标识按需刷新其存储在 cookie 中的标识.

Startup.Auth.cs 文件中,cookie 设置为如下重新生成:

app.UseCookieAuthentication(new CookieAuthenticationOptions{AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,LoginPath = new PathString("/Account/Login"),提供者 = 新的 CookieAuthenticationProvider{OnValidateIdentity = SecurityStampValidator.OnValidateIdentity(验证间隔:TimeSpan.FromMinutes(30),regenerateIdentityCallback: ((manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)),getUserIdCallback: ((claimsIdentity) => int.Parse(claimsIdentity.GetUserId())))}});

但是我无法弄清楚如何在代码中刷新 User.Identity 上的内容,即在我需要刷新身份 cookie 时强制刷新.

我希望能够以编程方式使用重新生成身份回调,这可能吗?

我的问题与此类似:如何在使用 Asp.Net Identity 2 将用户添加到角色后使 .AspNet.ApplicationCookie 失效?

但是我想刷新而不是使 cookie 无效.

编辑


在查看链接的问题后,我尝试了以下操作(没有完整的错误处理):

IOwinContext context = Request.GetOwinContext();QuizSparkSignInManager manager = context.Get();ClaimsIdentity newIdentity = manager.CreateUserIdentity(manager.UserManager.FindById(User.Identity.GetUserId()));AuthenticateResult authenticationContext =等待 context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie);如果(身份验证上下文!= null){context.Authentication.AuthenticationResponseGrant = new AuthenticationResponseGrant(newIdentity, authenticationContext.Properties);}bool first2 = User.IsInRole("Turtle");

Edit2:但是用户似乎仍然没有刷新.在页面重新加载时,它们似乎会刷新,我是否认为这是因为 User.Identity cookie 是请求的一部分,不能在代码中更改?

解决方案

如果您尝试向已登录的用户添加新角色,则需要将用户注销.然后使用新角色创建新身份并使用新身份登录用户.这是更新 cookie 的唯一方法.

检查用户属性是否已更改的最佳位置是您已经使用的回调:CookieAuthenticationProvider.OnValidateIdentity.像这样的东西.

app.UseCookieAuthentication(new CookieAuthenticationOptions{//其他的东西提供者 = 新的 CookieAuthenticationProvider{//这个函数在每个 http 请求中执行,并且在管道的早期执行//在这里您可以访问 cookie 属性和其他低级内容.//在这里设置失效是有意义的OnValidateIdentity = 异步上下文 =>{//如果用户的安全标记已更改,则使用户 cookie 无效var invalidateBySecirityStamp = SecurityStampValidator.OnValidateIdentity(验证间隔:TimeSpan.FromMinutes(30),regenerateIdentity: (manager, user) =>user.GenerateUserIdentityAsync(manager));等待 invalidateBySecirityStamp.Invoke(context);if (context.Identity == null || !context.Identity.IsAuthenticated){返回;}if(/*需要更新cookie*/){//获取用户管理器.它必须在 OWIN 注册var userManager = context.OwinContext.GetUserManager();var username = context.Identity.Name;//获取具有更新属性的新用户身份var updatedUser = await userManager.FindByNameAsync(username);//从用户对象中的新数据更新身份var newIdentity = updatedUser.GenerateUserIdentityAsync(manager);//杀死旧饼干context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);//重新登录var authenticationProperties = new AuthenticationProperties() { IsPersistent = context.Properties.IsPersistent };context.OwinContext.Authentication.SignIn(authenticationProperties, newIdentity);}}}});

免责声明 - 从未测试过,甚至没有尝试编译它.

也可以查看我的其他答案以供参考 - 几乎相同的一段代码,但目标不同.>

UPD:关于问题的另一部分 - 如何检测角色更改:
我能想到一个方法 - 在用户记录上有另一个 GUID.类似于 SecurityStamp,但不被框架使用.称之为MySecurityStamp.在登录时将 MySecurityStamp 的值作为声明添加到 cookie.在每个请求中,将 cookie 中 MySecurityStamp 的值与数据库中的值进行比较.如果值不同 - 重新生成身份的时间.并在添加/删除每个新角色时为数据库中的用户修改 MySecurityStamp.这将涵盖所有浏览器中的所有会话.

I am having trouble getting ASP Identity to refresh its Identity stored in a cookie on demand.

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())))
                }
            });

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?

My problem is similar to this one : How to invalidate .AspNet.ApplicationCookie after Adding user to Role using Asp.Net Identity 2?

However I want to refresh rather than invalidate the cookie.

Edit


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: 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?

解决方案

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.

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.

Also can see my other answer for reference - pretty much the same piece of code, but different goal.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆