ASP.NET Identity, add another user to role instantly (they don't have to log out and in again)

不羁的心 提交于 2019-12-03 09:32:46

问题


First of all, I'm aware of this question: MVC 5 AddToRole requires logout before it works?

and this one: What is ASP.NET Identity's IUserSecurityStampStore<TUser> interface?

so please don't mark this as a duplicate.

I'm trying to add another user to a role (i.e. the user we're adding to the role is not the current user. If they are, the answer to first question I linked to is sufficient.)

Like so:

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

The two situations I'm doing this in are: from an admin page, where the current user is the administrator; and a webhook secured with basic authentication (where there is no current user at all).

THE PROBLEM: if the user that this change applies to is logged in and using the app, I need the "add to role" change to apply instantly. They shouldn't have to log out and in again for the change to happen, and it needs to happen straight away.

Thanks everyone.

EDIT: By the way, User.IsInRole(roleName) requires logout and login to reflect being added to the new role. UserManager.IsInRole(userID, roleName) does not, because (I assume) it goes straight to the database tables to check. But if the user hits an action method secured with the role they've just been added to, they still have to log in again, which is fair enough. Still curious if there's a way around this.

EDIT: Here is the source code for the Authorize attribute: https://github.com/ASP-NET-MVC/aspnetwebstack/blob/4e40cdef9c8a8226685f95ef03b746bc8322aa92/src/System.Web.Mvc/AuthorizeAttribute.cs

It uses User.IsInRole, which is essentially why we need to log in again. It seems the method to override is AuthorizeCore(HttpContextBase httpContext). I'm not brave or good enough to mess with this right now but if you want to have a go lots of people will find this helpful.


回答1:


Starting from the bottom of your question. User.IsInRole() goes into user cookie and checks what roles are stored in that cookie. Hence it requires relogin for changes to take effect. And yes, you are correct in saying that UserManager.IsInRole() checks with database, not with the cookie.

To make sure role changes are applied immediately you need to check for change in roles on every request. To do that in Startup.Auth.cs find this line:

OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
    validateInterval: TimeSpan.FromMinutes(0), // <-- This is zero. Check on every request
    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)),

This is a framework's way of updating cookie. By default validateInterval is set for 30 minutes. If you set it to zero, the system will create a new cookie with updated roles on every request. This might be too much DB-load if you have enough users hitting your system at the same time. So I'd increase the timespan to 30-seconds-1-2minutes.

This feature was built as a way to logout all sessions by a single password change. But also works well for your purposes.




回答2:


In ASP.NET Core, SignInManager.RefreshSignInAsync() solves this.




回答3:


For ASP.NET Core Identity 2 the solution is to use:

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

To force an update every minute or use TimeSpan.Zero to force an update everytime the user accesses the page (notice that everytime a database request is performed).

Also make sure that if you overwrite the cookie events do not use:

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

But overwrite the Events you need directly as otherwise validation is not called:

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


来源:https://stackoverflow.com/questions/36766191/asp-net-identity-add-another-user-to-role-instantly-they-dont-have-to-log-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!