Search code examples
asp.net-mvcasp.net-identityrolesclaims

Custom role provider with Claims


I have User table in my database where I keep user's role (master admin, admin, developer). I want to authorize some controllers so only master admin can have access.

namespace TicketSystem.Controllers
{
    public class UserCredentials : ClaimsPrincipal, IIdentity, IPrincipal
    {
         public IIdentity Identity { get; private set; }
         public int UserId { get; set; }
         public string FirstName { get; set; }
         public string LastName { get; set; }
         public string[] roles { get; set; }

         public string email { get; set; }

         override
         public bool IsInRole(string role)
         {
             if (roles.Any(r => role.Contains(r)))
             {
                 return true;
             }
             else
             {
                 return false;
             }
         }

         public UserCredentials() { }
         public UserCredentials(ClaimsPrincipal principal)
             : base(principal)
         {
         }

         public UserCredentials(int userId, string email, string firstName, string lastName, string[] roles)
         {

             this.Identity = new GenericIdentity(email);
             this.UserId = userId;

             this.email = email;
             this.FirstName = firstName;
             this.LastName = lastName;
             this.roles = roles;

         }


         override
         public string ToString()
         {
             return UserId + "";
         }

    }
}

This is my login method

UserCredentials loggedUser = null;
User loginUser = db.tblUser.Where(x => x.email == model.UserName).FirstOrDefault();
loggedUser = new UserCredentials( loginUser.idUser, 
                 loginUser.email, loginUser.firsName, loginUser.lastName, new string[] { loginUser.role });
if (loggedUser != null)
{
    var identity = new ClaimsIdentity(new[] { 
                    new Claim(ClaimTypes.Name, loggedUser.email),
                    new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", User.Identity.AuthenticationType),
                    new Claim(ClaimTypes.NameIdentifier, loggedUser.FirstName),
                    new Claim(ClaimTypes.Role, loggedUser.roles[0])
                    }, "ApplicationCookie");

    var ctx = Request.GetOwinContext();
    var authManager = ctx.Authentication;

    authManager.SignIn(identity);

I try with this

public class CustomRoleProvider : RoleProvider
{
    public override bool IsUserInRole(string username, string roleName)
    {
        using (var usersContext = new TicketSystemEntities())
        {
            var user = usersContext.tblUser.SingleOrDefault(u => u.email == username);
            if (user == null)
                return false;
            return user.role != null && user.role==roleName;
        }
    }
}

but I don't know how to configure web.Config. Also I'm having errors such as

TicketSystem.Models.CustomRoleProvider' does not implement inherited abstract member 'System.Web.Security.RoleProvider.GetUsersInRole(string)

I was searching other examples but I didn't find any example where the author uses Claim


Solution

  • RoleProvider is an abstract class, you have to implement all abstract methods to compile your CustomRoleProvider.

    In the Web.config you need to add section roleManager and add your custom provider. Something like this:

    <roleManager enabled="true" defaultProvider="CustomRoleProvider">
      <providers>
        <clear/>
        <add name="CustomRoleProvider" 
           type="TicketSystem.Models.CustomRoleProvider, 
                 TicketSystem, Version=1.0.0.0, Culture=neutral" 
           connectionStringName="TicketSystemEntities"
           enablePasswordRetrieval="false" enablePasswordReset="true"/>
      </providers>
    </roleManager>
    

    For reference check RoleProvider docs https://msdn.microsoft.com/en-us/library/system.web.security.roleprovider(v=vs.140).aspx and roleManager docs https://msdn.microsoft.com/en-us/library/vstudio/ms164660%28v=vs.100%29.aspx