i have a problem with my custom role providor "string[] GetRolesForUser(string username)" method but the proccess dont go through it. My code is:
Controller (Just a piece of it):
[Authorize(Roles="Administrator")]
public class UsersController : AdminBaseController
{
private IUsersRepository users;
private IDepartmentsRepository departments;
public UsersController()
{
this.users = new UsersRepository(new TicketsContext());
this.departments = new DepartmentsRepository(new TicketsContext());
}
}
Custom Role Provider:
public class CustomRoleProvider : RoleProvider
{
public override bool IsUserInRole(string username, string roleName)
{
var userRoles = GetRolesForUser(username);
return userRoles.Contains(roleName);
}
public override string[] GetRolesForUser(string username)
{
//Return if the user is not authenticated
if (!HttpContext.Current.User.Identity.IsAuthenticated)
return null;
//Return if present in Cache
var cacheKey = string.Format("UserRoles_{0}", username);
if (HttpRuntime.Cache[cacheKey] != null)
return (string[])HttpRuntime.Cache[cacheKey];
//Get the roles from DB
var userRoles = new string[] { };
var user = db.Users.Where(u => u.email == username).FirstOrDefault();
if (user != null)
{
if(user.access_level == 0)
{
userRoles = new[] { "Administrator" };
}
else
{
userRoles = new[] { "Normal" };
}
}
//Store in cache
HttpRuntime.Cache.Insert(cacheKey, userRoles, null, DateTime.Now.AddMinutes(_cacheTimeoutInMinutes), Cache.NoSlidingExpiration);
// Return
return userRoles.ToArray();
}
}
Web.config
<!-- Custom Role Provider -->
<roleManager enabled="true" defaultProvider="TicketsRoleProvider">
<providers>
<add name="TicketsRoleProvider"
type="Tickets.CustomRoleProvider"
cacheTimeoutInMinutes="30" />
</providers>
</roleManager>
I cant get it to work, and i dont know why.
Can anyone help me pls ?
Thanks
I can't see anything obvious, but I would:
Remove the check for "HttpContext.Current.User.Identity.IsAuthenticated" in the GetRolesForUser method. This method should just get the roles for the username supplied as an argument.
To debug, I'd start by examining
HttpContext.Current.User.GetType()
inside a controller action method (one that isn't secured). Is it of typeSystem.Web.Security.RolePrincipal
?You should implement
IsUserInRole
in your customRoleProvider
. The implementation can just check that the supplied role is in the array returned byGetRolesForUser
. I don't think this is your problem though:IsUserInRole
isn't used byRolePrincipal
(though it is used bySystem.ServiceModel.Security.RoleProviderPrincipal
if you use ASP.NET roles in a WCF service, so it's a good idea to implement it anyway.UPDATE
You've confirmed
HttpContext.Current.User
is aRolePrincipal
. I suggest you examine it closely using the debugger. In particular examine:the
ProviderName
property, which should match the name of your custom RoleProvider.the
Identity
property, which should match the name of the current user.You might also try calling
HttpContext.Current.User.IsInRole
from code in your controller. The first time this is called, it should call your custom RoleProvider's GetRolesForUser method.You can also try calling the
RolePrincipal.SetDirty()
method: this marks the cached role list as having been changed, and the next call toIsInRole
orGetRoles
should call your custom RoleProvider's GetRolesForUser method again.