Bartosz
Bartosz

Reputation: 4592

User.IsInRole doesn't work

I have ASP.NET MVC 4 application. I use Simple Membership Provider allowing to tick remember me checkbox under login form. If ticked, persitent cookie .ASPXAUTH is created which expires 100 days from login date. And everything works fine, apart of main menu of the application.

Some parts of the menu are available for admin users only. I use:

@if (User.IsInRole("Administrator")) { @Html.Partial("_MainMenuPartial") }

to lock them from being rendered for regular user. This approach works fine just after logging into the system. When I return after a while and persistent cookie is used to authenticate me, I do get logged in, but

@User.IsInRole("Administrator")

returns "False" so I can't see admin menu items. At the same time

@User.Identity.Name

returns proper login name and

@User.Identity.IsAuthenticated

returns "True", what proves that persistent cookie works fine. Why can't I access user roles even though user is authenticated by the system then?

Upvotes: 30

Views: 49272

Answers (19)

Олег Ладыко
Олег Ладыко

Reputation: 112

@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

...

await UserManager.IsInRoleAsync(await UserManager.GetUserAsync(User),"admin")

Upvotes: 0

Ali Yıldız&#246;z
Ali Yıldız&#246;z

Reputation: 438

Clear all cookies and try to login again. If we changed our roles, the cookie might not be aware of it. Reset the Cookies and create a cookie with your new roles and try again.

Upvotes: 1

Dmitri
Dmitri

Reputation: 766

Several things could be going on and here are few general things to try:

  1. Try to run in debug mode and make sure that the line of code gets executed - silly but might happen
  2. As stated in other answers, try to log off and log back in
  3. Make sure the role is spelled out correctly
  4. Make sure that the proper user is assigned to the proper role id
  5. Try to republish the entire solution to the server - in my case, everything worked fine locally but not on the server until full delete all and republish
  6. If all fails, try to run out of a box project and test it before adding complexity

Upvotes: 0

VFein
VFein

Reputation: 1061

If you're using IdentityManager by Brock Allen to create roles and assign them to users then you should read this article: https://github.com/IdentityManager/IdentityManager.AspNetIdentity/issues/3

You'll need to uncomment the following line:

this.RoleClaimType = System.Security.Claims.ClaimTypes.Role;

Now you'll realize that your user that used to be in roles is no longer in them, and you'll have to re add them. If you take a look at the AspNetUserClaims table, you'll see claimType of Role and 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' you want the later.

Once you do this, User.IsInRole("rolename") behaves as expected.

I hope this helps someone, took me a while to figure this out.

Upvotes: 2

Carlos Maia de Morais
Carlos Maia de Morais

Reputation: 320

Paste this code in Global.asax

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        {
            HttpCookie authCookie =
                Context.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                FormsAuthenticationTicket authTicket =
                    FormsAuthentication.Decrypt(authCookie.Value);
                string[] roles = authTicket.UserData.Split(new Char[] { ',' });
                GenericPrincipal userPrincipal =
                    new GenericPrincipal(new GenericIdentity(authTicket.Name), roles);
                Context.User = userPrincipal;
            }
        }

        protected class RolesAttribute : AuthorizeAttribute
        {
            public RolesAttribute(params string[] roles)
            {
                Roles = String.Join(",", roles);
            }
        }

Upvotes: 0

Ashok B
Ashok B

Reputation: 61

If you are using latest Identity framework please see if you are using following

services.AddIdentity<IdentityUser,IdentityRole>()
        .AddEntityFrameworkStores<WebUserContext>()
        .AddDefaultTokenProviders();

If you are using AddDefaultIdentity Roles don't get populated.

services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<WebUserContext>()
        .AddDefaultTokenProviders();

Upvotes: 6

agressen
agressen

Reputation: 469

None of these answers worked for me, but I did find the answer here: https://thinkthencode.wordpress.com/2016/04/24/azure-ad-using-app-roles-for-authorization/

The key was adding the following to Startup.Auth.cs:

TokenValidationParameters = new TokenValidationParameters
{
    RoleClaimType = "roles"
}

Upvotes: 2

Marcos R
Marcos R

Reputation: 803

Old question, but there's some missing information here. I ran into the same issue, and there's one thing to keep in mind. If you test the user identity (like User.IsInRole("admin")) just after authenticate (without send the response to client), Identity framework has not populated this session info yet (or at least, I could not found the way to do that). This info you're requesting for, is populated at some point after your controller return. If you want (I.E.) to redirect to different views after login, depending on the user role, you'll have to use a custom authorization filter.

Upvotes: 8

JSideris
JSideris

Reputation: 5261

I've been struggling with the MVC5 role manager for some time now. I've verified that User.IsInRole can return different results at the same time, and apparently this is because the User object is cached and needs to be invalidated. One way to do this is to log out and log back in again as one of the answers here specified. Just throw this in the controller that adds the new role:

        UserManager.AddToRole(User.Identity.GetUserId(), "Administrator");

        var updatedUser = await UserManager.FindByNameAsync(User.Identity.Name);
        var newIdentity = await updatedUser.GenerateUserIdentityAsync(UserManager);
        AuthenticationManager.SignOut();
        AuthenticationManager.SignIn(newIdentity);

However, if the user has your application open in other windows this won't update all of them.

Upvotes: 1

ViniBH
ViniBH

Reputation: 21

The "EmailConfirmed" of this account probably still false, try to change it to true

Database Screenshot

Upvotes: 2

Music Backup
Music Backup

Reputation: 59

Add Page in front of User. This works: Page.User.IsInRole("Administrator")

Upvotes: -1

Radovan
Radovan

Reputation: 11

Quite old topic but can confirm in vs 2015 Web forms application works solution:

<modules>
    <remove name="FormsAuthenticationModule" />
    <remove name="RoleManager" /> <!--add this to web config-->
</modules>

Upvotes: 1

Pažout
Pažout

Reputation: 2171

Problem using roles with MVC5

I found a solution. In my web.config:

<modules>
    <remove name="FormsAuthenticationModule" />
    <remove name="RoleManager" />
</modules>

I added remove name="RoleManager" line, and the new AspNet.Identity code took over allowing me to use User.IsInRole(..)

http://forums.asp.net/t/1952572.aspx?Problem+using+roles+with+MVC5

Upvotes: 21

Blake
Blake

Reputation: 308

For my code it had to be plural, not singular:

User.IsInRole("Administrators")

Upvotes: -6

Cem Mutlu
Cem Mutlu

Reputation: 2099

I had a smilar issue. In my case the problem solved when i log off and log in again.

Upvotes: 33

xfan
xfan

Reputation: 151

Have you tried adding

[InitializeSimpleMembership]

in the controller where you're doing the check?

Upvotes: 6

MattSull
MattSull

Reputation: 5564

I had a similar problem with IsUserInRole returning false. By placing a watch on it, I was able to overcome the problem by using the overload described below. Try it, put a break point where you're getting false, and see what happens.

@if (Roles.IsUserInRole(Model.UserName, "Administrator"))

I'm pretty sure you could also use User.Identity.Name as the first parameter.

Upvotes: 5

pollirrata
pollirrata

Reputation: 5286

I had a similar issue, but in my case the problem was that the Session timeout was not synced with the authentication timeout, so I was not kicked out automatically but my session was being expired and, since my allowed operations were stored in a Session Variable, I was not able to retrieve the correct options for the current user.

Try checking if your session is not expired even if you're still logged in

Upvotes: 1

Sergey
Sergey

Reputation: 3213

I had a similar issue, seems like authentication module is not wired up completely with the SimpleMembershipProvider. To get around that problem, you can use a Role class to access needed information. For example to check if the use in role you can use the following:

Roles.GetRolesForUser("sergey").Contains("Developer")

And so other useful methods when working wit SimpleMembershipProvider roles:

   Roles.RoleExists("Developer")
   Roles.CreateRole("Developer");
   Roles.AddUserToRole("sergey", "Developer");

Upvotes: 3

Related Questions