ASP.NET身份,立即将另一个用户添加到角色(他们不必再次注销)

时间:2016-04-21 10:01:24

标签: c# asp.net asp.net-mvc asp.net-identity asp.net-roles

首先,我知道这个问题:MVC 5 AddToRole requires logout before it works?

和这一个:What is ASP.NET Identity's IUserSecurityStampStore<TUser> interface?

所以请不要将其标记为副本。

我正在尝试将另一个用户添加到某个角色(即我们添加到该角色的用户不是当前用户。如果是这样,我链接到的第一个问题的答案就足够了。)

像这样:

IdentityResult result = await userManager.AddToRoleAsync(userID, roleName);

我正在做的两种情况是:从管理页面,当前用户是管理员;以及基本身份验证保护的webhook(根本没有当前用户)。

问题:如果此更改适用的用户已登录并使用该应用程序,我需要立即应用“添加到角色”更改。他们不应该退出并再次进行更改,而且需要立即进行。

谢谢大家。

编辑: 顺便说一句,User.IsInRole(roleName)要求注销和登录以反映被添加到新角色。 UserManager.IsInRole(userID,roleName)没有,因为(我假设)它直接进入数据库表进行检查。但是如果用户点击了一个以他们刚刚添加的角色担保的动作方法,他们仍然需要再次登录,这是公平的。仍然很好奇,如果有办法解决这个问题。

编辑: 以下是授权属性的源代码:https://github.com/ASP-NET-MVC/aspnetwebstack/blob/4e40cdef9c8a8226685f95ef03b746bc8322aa92/src/System.Web.Mvc/AuthorizeAttribute.cs

它使用User.IsInRole,这本质上是我们需要再次登录的原因。似乎覆盖的方法是AuthorizeCore(HttpContextBase httpContext)。我现在不是很勇敢或者不够好,但是如果你想要有很多人会觉得这很有帮助。

3 个答案:

答案 0 :(得分:5)

从问题的底部开始。 zip进入用户cookie并检查该cookie中存储的角色。因此,它需要重新定义才能使更改生效。是的,你说User.IsInRole()检查数据库而不是cookie是正确的。

要确保立即应用角色更改,您需要检查每个请求的角色更改。要在UserManager.IsInRole()中执行此操作,请找到以下行:

Startup.Auth.cs

这是一种框架更新cookie的方法。默认情况下,OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromMinutes(0), // <-- This is zero. Check on every request regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)), 设置为30分钟。如果将其设置为零,系统将在每个请求上创建一个包含更新角色的新cookie。如果您有足够的用户同时访问您的系统,这可能会导致DB负载过多。所以我将时间跨度增加到30秒-2-2分钟。

此功能是作为通过单个密码更改注销所有会话的方法而构建的。但也适用于您的目的。

答案 1 :(得分:3)

在ASP.NET Core中,SignInManager.RefreshSignInAsync()解决了这个问题。

答案 2 :(得分:0)

对于ASP.NET Core Identity 2,解决方案是使用:

services.Configure<SecurityStampValidatorOptions>(options =>
{
    options.ValidationInterval = TimeSpan.FromMinutes(1);
});

每分钟强制更新,或使用TimeSpan.Zero在用户每次访问页面时强制更新(请注意,每次执行数据库请求时)。

还要确保如果您覆盖cookie事件,请不要使用:

        services.ConfigureApplicationCookie(options =>
        {
            options.Events = new CookieAuthenticationEvents(){
            ...
            };
        }

但是直接覆盖您需要的事件,否则不会进行验证:

        services.ConfigureApplicationCookie(options =>
        {
            options.Events.OnRedirectToLogin = ctx => {
            ...
            };
        }