views:

1109

answers:

3

In a custom role provider (inheriting from RoleProvider) in .NET 2.0, the IsUserInRole method has been hard-coded to always return true:

public override bool IsUserInRole(string username, string roleName) { return true; }

In an ASP.NET application configured to use this role provider, the following code returns true (as expected):

Roles.IsUserInRole("any username", "any rolename"); // results in true

However, the following code returns false:

Roles.IsUserInRole("any rolename"); // results in false

Note that User.IsInRole("any rolename") is also returning false.

  1. Is this the expected behavior?
  2. Is it incorrect to assume that the overload that only takes a role name would still be invoking the overridden IsUserInRole?

Update: Note that there doesn't seem to be an override available for the version that takes a single string, which has led to my assumption in #2.

+4  A: 

I looked at Roles.IsUserInRole(string rolename) in .net reflector, and it resolves to the following:

public static bool IsUserInRole(string roleName)
{
    return IsUserInRole(GetCurrentUserName(), roleName);
}

I would take a look at your current user. Here's why:

private static string GetCurrentUserName()
{
    IPrincipal currentUser = GetCurrentUser();
    if ((currentUser != null) && (currentUser.Identity != null))
    {
        return currentUser.Identity.Name;
    }
    return string.Empty;
}

I would be willing to bet this is returning an empty string because you either don't have a Current User, or its name is an empty string or null.

In the IsUserInRole(string username, string roleName) method, there is the following block of code right near the beginning:

   if (username.Length < 1)
   {
       return false;
   }

If your GetCurrentUserName() doesn't return anything meaningful, then it will return false before it calls your overridden method.

Moral to take away from this: Reflector is a great tool :)

Andrew Rollings
Much appreciated! I have downloaded the Reflector tool now, thanks for pointing me towards it. You were correct about the username being blank, I am using anonymous authentication, resulting in the identity being System.Security.Principal.GenericIdentity which happens to have a blank Name attribute.
J c
Yeah, I tend to rely on reflector more than Microsoft's own documentation :)
Andrew Rollings
A: 

Also beware if you have selected cacheRolesInCookie="true" in the RoleManager config. If you have added a new role to the database, it might be looking at the cached version in the cookie.

I had this problem and the solution was to delete the cookie and re-login.

Junto
A: 

This may help someone - be aware:

If you are using the login control to authenticate - the username entered into the control becomes the HttpContext.Current.User.Identity.Name which is used in the Roles.IsUserInRole(string rolename) and more specifically - the membership's GetUser() method. So if this is the case make sure you override the Authenticate event, validate the user in this method and set the username to a value that your custom membership provider can use.

 protected void crtlLoginUserLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
    bool blnAuthenticate = false;
    string strUserName = crtlLoginUserLogin.UserName;

    if (IsValidEmail(strUserName))
    {

        //if more than one user has email address - must authenticate by username.

        MembershipUserCollection users = Membership.FindUsersByEmail(strUserName);
        if (users.Count > 1)
        {
            crtlLoginUserLogin.FailureText = "We are unable to determine which account is registered to that email address. Please enter your Username to login.";

        }
        else
        {
            strUserName = Membership.GetUserNameByEmail(strUserName);
            blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);

            //setting the userLogin to the correct user name (only on successful authentication)
            if (blnAuthenticate)
            {
                crtlLoginUserLogin.UserName = strUserName;
            }

        }


    }
    else
    {
        blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
    }

    e.Authenticated = blnAuthenticate;

}
FiveTools

related questions