Kassem
Kassem

Reputation: 8266

Custom Authorize Attribute (follow-up)

Ok following up with this thread, here's what I came up with...

public class SharweAuthorizeAttribute : AuthorizeAttribute
{
    private bool isAuthenticated = false;
    private bool isAuthorized = false;
    public new string[] Roles { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (SessionManager.CheckSession(SessionKeys.User) == true)
        {
            isAuthenticated = true;
            foreach (string role in Roles)
            {
                if (RolesService.HasRole((string)role))
                    isAuthorized = true;
            }
        }
        return (isAuthenticated && isAuthorized);
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!isAuthenticated)
        {
            filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary 
                            {
                                { "action", "User" },
                                { "controller", "Login" }
                            });
        } else if(!isAuthorized) {
            filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary 
                            {
                                { "action", "Home" },
                                { "controller", "Error" }
                            });
        }
    }
}

How/why I came up with this? Because I believe the AuthorizeAttribute workflow goes as follows:

  1. First, AuthorizeCore is triggered. If it returns true, the user is authorized. If it returns false, HandleUnauthorizedRequest is triggered. Is that right?
  2. I read somewhere that I need to use the new keyword to override a property. Therefore, this is how I overrode the Roles property. But what if the overriding property was of a different type of the initial one (the one in the base class), does that also hide it or creates a totally different property?

So what do you think? Should that actually work? I cannot test it now because I haven't set up the UI (waiting for the designer to get done with the design)... In fact, this is the first time I appreciate the benefits of TDD, I used to think it's utterly stupid and useless, but I was wrong :)

P.S: On this thread, @tvanfosson is setting the CachePolicy of the context (I think), could someone explain that and why I might need to do that please?

Thanks in advance.

Upvotes: 4

Views: 1834

Answers (1)

Novkovski Stevo Bato
Novkovski Stevo Bato

Reputation: 1043

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    private readonly bool _authorize;
    private readonly string[] _roles;

    public CustomAuthorizeAttribute(string roles)
    {
        _authorize = true;
        _roles = roles.Split(',');
    }

    public CustomAuthorizeAttribute(string roles, bool isAdminPath)
    {
        _authorize = true;
        _roles = roles.Split(',');
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        //if controller have role auth and user is not loged
        if(_authorize && !httpContext.User.Identity.IsAuthenticated)
            return false;

        // if controller have role auth and user is loged
        if(_roles != null)
        {
            //grab user roles from DB
            var UserRole = RoleRepository.GetUserRole(new Guid(httpContext.User.Identity.Name));
            if (_roles.Contains(UserRole))
               return true;
        }
        return false;
    }
}

In Controller

[CustomAuthorize("Administrator,Company,OtherRole")]
public ActionResult Test(){
    return View();
}

Upvotes: 2

Related Questions