Showing posts with label GenericPrincipal. Show all posts
Showing posts with label GenericPrincipal. Show all posts

Saturday, May 19, 2012

Role management with Windows Authentication

Solution System.Security.Prinicipal.GenericPrincipal class helps you to create a custom principal. It's constructor takes following parameters.
  • IIdentity Identity - Identity of the current user.
  • string[] roles - Array of current user roles.
Steps to create a custom prinicipal class
  1. Create a custom principal by deriving it from GenericPrinicipal class by passing following parameter values to it's constructure.
    Identity : HttpContext.Current.User.Identity .
    Roles : Array of user roles . User roles can be fetched from the DB or from a service.
  2. Implements the IsInRole virtual property with custom logic to check if the current user is in a specific role.
Components of the solutions LoggedInUser - It contains the properties of the user.
UserRole - it is enumeration of all roles available in the application.
CustomPrincipal - The prinicipal class which is inherited from GenericPrinicipal and implements its construction and IsInRole property.
UserContext - Its a facade class that provides the static method GetPrinicipal() which returns a prinicipal object for the current user.
UserHelper - A static helper class with helper methods to obtain prinicipal, user object and user properties.
Code
    public class LoggedInUser
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string DisplayName { get; set; }
        public UserRole Role { get; set; }
        
        public static LoggedInUser Empty = new LoggedInUser()
        {
            UserName = string.Empty,
            DisplayName = string.Empty,
        };

        public bool IsAuthorized
        {
            get
            {
                return this.UserId > 0 && this.Role != UserRole.Undefined;
            }
        }

        public string[] Roles
        {
            get
            {
                return new string[] { this.Role.ToString() };
            }
        }
    }

    public enum UserRole
    {
        Undefined = 0,
        Representative = 1,
        Manager = 2,
        [Description("System Administrator")]
        Administrator = 3,
        Supervisor = 4
    }
    
    public class CustomPrincipal : GenericPrincipal
    {
        #region Data Members
        
        private List _roles;
        private LoggedInUser _user;

        #endregion

        #region Construction

        public CustomPrincipal(IIdentity identity, LoggedInUser user) : this(identity, user.Roles, user)
        {
        }

        public CustomPrincipal(IIdentity identity, IEnumerable roles, LoggedInUser user) : base(identity, roles.ToArray())
        {
            DebugHelper.AssertAndThrow(identity != null, "No identity passed to principal");
            DebugHelper.AssertAndThrow(user != null, "No user data passed to principal");

            _roles = new List(roles);
            _user = user;            
        }

        public static CustomPrincipal Empty = new MatsPrincipal(new GenericIdentity(""), new List(), LoggedInUser.Empty);

        #endregion

        #region Properties

        public string[] Roles { get { return _roles.ToArray(); } }

        public string UserName { get { return _user.UserName; } } 

        public string DisplayName { get { return _user.DisplayName; } }

        public UserRole Role { get { return _user.Role; } }

        public int UserId { get { return _user.UserId; } }

        public bool IsAuthorized { get { return _user.IsAuthorized; } }

        #endregion

        #region Methods

        public bool IsInRole(UserRole role)
        {
            return IsInRole(role.ToString());
        }

        #endregion
    }
    
    public class UserContext
    {
        public static CustomPrincipal GetPrinicipal(string userName)
        {
           var prinicipal = CustomPrincipal.Empty;
           if (string.IsNullOrEmpty(userName))
           {
               return prinicipal;
           }
           var user = userService.GetLoggedInUser(userName);
           prinicpal = new CustomPrinicipal(HttpContext.Current.User.Identity, user);
           return principal;
        }
    }

    public static class UserHelper
    {
        public static CustomPrincipal CurrentUser
        {
            get
            {
                string userName = UserHelper.CurrentUserName;

                return (userName.IsNullOrWhiteSpace()) ?
                    CustomPrincipal.Empty :
                    UserContext.GetPrincipal(userName);
            }
        }
        
        public static string CurrentUserName
        {
            get
            {
                string userName = (HttpContext.Current != null && HttpContext.Current.User != null) ?
                    HttpContext.Current.User.Identity.Name :
                    string.Empty;

                return userName;
            }
        }
        
        public static int CurrentUserId
        {
            get
            {
                return UserHelper.CurrentUser.UserId;
            }
        }

        public static UserRole CurrentUserRole
        {
            get
            {
                return UserHelper.CurrentUser.Role;
            }
        }
    }