ASP.NET ID, add another user to the role instantly (they donโ€™t need to log out and again)

First of all, I know about this question: Does MVC 5 AddToRole require logging out before it works?

and this one: What is the IUserSecurityStampStore <TUser> interface?

therefore, please do not mark this as a duplicate.

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

Same:

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

Two situations in which I do this are: from the admin page, where the current user is the administrator; and a webhook provided with basic authentication (where there is no current user at all).

PROBLEM: if the user this change belongs to logs in and uses the application, I need the "add to role" changes to be applied instantly. They will not need to log out again and again for this to happen, and this should happen right away.

Thanks to everyone.

EDIT: By the way, User.IsInRole (roleName) requires logging out and logging in to reflect the addition to the new role. UserManager.IsInRole (userID, roleName) does not do this because (I assume) it goes directly to the database tables that need to be checked. But if the user clicks on an action method protected by the role to which they have just been added, they will still have to log in again, which is fair enough. Still curious if there is a way around this.

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

It uses User.IsInRole, so we have to log in again. It seems like the override method is AuthorizeCore (HttpContextBase httpContext). I'm not brave and not good enough to end this right now, but if you want a lot of people to find it useful.

+10
c # asp.net-mvc asp.net-identity asp.net-roles
source share
3 answers

Starting at the bottom of your question. User.IsInRole() goes into the user's cookie and checks which roles are stored in this cookie. Therefore, a transition is required to transition to change. And yes, you are right in saying that UserManager.IsInRole() checks with the database and not with the cookie.

To ensure that role changes are applied immediately, you need to check the role change on every request. To do this, 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 the basic way to update cookies. By default, validateInterval set within 30 minutes. If you set it to zero, the system will create a new cookie with updated roles for each request. This can be too much DB load if you have enough users hitting your system at the same time. Therefore, I would increase the time interval to 30 seconds - 1-2 minutes.

This feature was created as a way to log out of all sessions with a single password change. But also works well for your purposes.

+4
source share

In the ASP.NET kernel, SignInManager.RefreshSignInAsync () solves this.

+3
source share

For ASP.NET Core Identity 2, the solution should use:

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

To force updates every minute or use TimeSpan.Zero to force updates every time a user accesses a page (note that every time a database query is executed).

Also make sure that if you are rewriting cookies, do not use:

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

But overwrite the events you need directly, because otherwise the check is not called:

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

All Articles