Question

In my MVC3 wep app, I have extended the Authorize attribute like below

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (Authenticate.IsAuthenticated() && httpContext.User.Identity.IsAuthenticated)
        {
            var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                var ticket = FormsAuthentication.Decrypt(authCookie.Value);
                var roles = ticket.UserData.Split('|');
                var identity = new GenericIdentity(ticket.Name);
                httpContext.User = new GenericPrincipal(identity, roles);
            }
        }
        return base.AuthorizeCore(httpContext);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {

        if (!Authenticate.IsAuthenticated())
            HandleUnauthorizedRequest(filterContext);


        base.OnAuthorization(filterContext);

    }

In my Actions, I use it like

    [MyAuthorize(Roles = "Member,Inspector,SalesRep,Admin,SuperAdmin")]
    public ActionResult OrderUpload()

Now, I have to specify each user role in every action. What I would like to do is specify something like below

    [MyAuthorize(Roles = "Member")]
    public ActionResult OrderUpload()

and this should allow any User Role that are equal or above "Member". So a "SalesRep" should be allowed, where as "Visitor", who is below the "Member" should not be allowed.

All User Roles are enum with increasing numbers

public enum UserAccountType
{
    Visitor = 5,
    Member = 10,
    Inspector = 15,
    SalesRep = 20,
    Admin = 25,
    SuperAdmin = 30
}

How do I modify MyAuthorizeAttribute to make this work?

Thanks

Was it helpful?

Solution

Here is my working code

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (Authenticate.IsAuthenticated() && httpContext.User.Identity.IsAuthenticated)
        {
            var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
            string[] roles = null;

            if (authCookie != null)
            {
                var ticket = FormsAuthentication.Decrypt(authCookie.Value);
                roles = ticket.UserData.Split('|');
                var identity = new GenericIdentity(ticket.Name);
                httpContext.User = new GenericPrincipal(identity, roles);
            }

            if (Roles == string.Empty)
                return true;

            //Assuming Roles given in the MyAuthorize attribute will only have 1 UserAccountType - if more than one, no errors thrown but will always return false
            else if ((UserAccountType)Enum.Parse(typeof(UserAccountType), roles[0]) >= (UserAccountType)Enum.Parse(typeof(UserAccountType), Roles))
                return true;
            else
                return false;
        }
        else
            return false;

        //return base.AuthorizeCore(httpContext);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!Authenticate.IsAuthenticated())
            HandleUnauthorizedRequest(filterContext);

        base.OnAuthorization(filterContext);
    }
}

OTHER TIPS

I don't use AuthorizeAttribute but ActionFilter (it's just me and that's how I learned it) but What I would do is add a property on the AuthorizeAttribute that gets updated when the Attribute gets triggered before the Action.

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    private string Role = "";

    public MyAuthorizeAttribute(string role){
        this.Role = role;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
          :
          :
          :
          // now do a check if the Role is authorized or not using your enum. 
          // return error page if not
          if(RoleisAuthorized)
            return; 
          else
            // error page

    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
          :
          :
          :
    }
}

Now after you got the Role, go get it from the enum and compare if the role is allowed to access the page or not, if not return an error page. So since I'm not familiar with OnAuthorization, I would place the process inside AuthorizeCore.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top