首先,我知道这个问题: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)。我现在不是很勇敢或者不够好,但是如果你想要有很多人会觉得这很有帮助。
答案 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 => {
...
};
}