Search code examples
c#.netasp.net-mvcasp.net-roles

ASP.NET MVC Roles and Security


Assume like this is my SampleController action method

public ActionResult AdminView()
{
    return View()
}

If want this controller method to be called if the logged in user belongs to admin role, otherwise this method call should be blocked and the user should get an some custom unauthorized access error page.

In my asp .net mvc web application, when the user logs in, I am storing the user role in a session as a string. And whenever there is a need to validate the user role, I compare the value stored in the session against a constant say "ADMIN_ROLE". But I am writing that piece of code to check for the user role in almost every controller action method and then either return an appropriate view for the user or an unauthorized access page view if the user role is restricted for the controller action method.

I googled and read that we can use something like this.

[Authorize(Roles="admin")]
public ActionResult AdminView()
{
  return View()
}

But I am not sure how the Authorize and the Roles keyword works. How when putting Roles = "Admin", is going to help in checking my user role string stored in the session, or how I can redirect a user to unauthorized page, in case the role does not match the role tagged for the action method.


Solution

  • As per my thinking you need to code for authorization.

    public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {
        private readonly RoleEnum[] _acceptedRoles;
    
        public AuthorizeAttribute(params RoleEnum[] acceptedroles)
        {
            _acceptedRoles = acceptedroles;
        }
    
        public AuthorizeAttribute(params bool[] allowAll)
        {
            if (allowAll[0])
                _acceptedRoles = new RoleEnum[] { RoleEnum.Admin, RoleEnum.user};
        }
    
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (SessionHelper.UserInSession == null)//user not logged in
            {
                FormsAuthentication.SignOut();
                filterContext.Result =
                     new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary {{ "controller", "Home" },
                                                 { "action", "Index" },
                                                 { "returnUrl",    filterContext.HttpContext.Request.RawUrl } });//send the user to login page with return url
                return;
            }
            if (!_acceptedRoles.Any(acceptedRole => SessionHelper.UserInSession.UserRoles.Any(currentRole => acceptedRole == currentRole.Role)))
                //allow if any of the user roles is among accepted roles. Else redirect to login page
                throw new UnauthorizedAccessException();
    
        }
    }
    

    This is also work for return URL.