Search code examples
asp.netasp.net-mvcasp.net-mvc-5asp.net-identityidentity

How to create dynamic role in asp.net mvc5


I want to create a dynamic role in ASP.NET MVC 5. I do not want to create hardcode roles in the authorization attribute .I want to create roles later.it's a test for my recruitment.Do you have sample code or video In this case? Just in ASP.NET MVC 5. Thanks in advance for your help


Solution

  • You mean you need dynamic authorization.

    In order to do this.

    1.You need to add two more tables(Except identity tables).

    1. AppContent (Columns:{Id, Resource, Function,Description})
    2. RoleRights (Columns:{Id, RoleName,AppContentId).

    2.Create CustomAuthorizeAttribute

    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class CustomAuthorize : AuthorizeAttribute
    {
        //Custom named parameters for annotation
        public string Source { get; set; }//Controller Name
        public string Function { get; set; }//Action Name
    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        { 
            //Is user logged in?
            if (httpContext.User.Identity.IsAuthenticated)
            {
    
                 if ((!string.IsNullOrEmpty(ResourceKey)) && (!string.IsNullOrEmpty(OperationKey)))
                {
                    //There are many ways to store and validate RoleRights 
                    //1.You can store in Database and validate from Database.
                    //2.You can store in user claim at the time of login and validate from UserClaims.
                    //3.You can store in session validate from session
    
                    //Below I am using database approach.
                    var loggedInUserRoles = ((ClaimsIdentity) httpContext.User.Identity).Claims
                                            .Where(c => c.Type == ClaimTypes.Role)
                                            .Select(c => c.Value);
    
                    //logic to check loggedInUserRoles has rights or not from RoleRights table
                    return db.RoleRights.Any( x=> x.AppContent.Source == Source && x.AppContent.Function == Function && loggedInUserRoles.Contains( x.AppContent.RoleName));
    
                }
    
            }
            //Returns true or false, meaning allow or deny. False will call HandleUnauthorizedRequest above
    
            return base.AuthorizeCore(httpContext);
        }
    
        //Called when access is denied
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            //User isn't logged in
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(filterContext);
                return;
    
            }
            //User is logged in but has no access
            else
            {
                filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary(new { controller = "Account", action = "NotAuthorized" })
                );
            }
    
        }
    
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            // Check for authorization
    
            if (string.IsNullOrEmpty(this.Source) && string.IsNullOrEmpty(this.Function))
            {
                this.Source = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                this.Function = filterContext.ActionDescriptor.ActionName;
            }
    
            base.OnAuthorization(filterContext);
        }
    }
    

    3. Assign CustomAuthorizeAttribute to the Controller Action

        [CustomAuthorize(Source= "Branch", Function = "Index")]
        public ActionResult Index()
        {
            return View(model);
        }
    
        [CustomAuthorize(Source = "Branch", Function = "Details")]
        public ActionResult Details(long? id)
        {
            return View(branch);
        }
    
        [CustomAuthorize(Source = "Branch", Function = "Create")]
        public ActionResult Create()
        { 
            return View();
        }
    

    4.Setup all of your application content like Source(Controller) and Function(Action) in AppContent table.

    5.Assign AppContents to a role for allowing to role to access this content.

    6.Assign User to Role.

    7.Run the application and test.