2

I have extended the Authorize attribute to include roles which comes from a cookie. Debugging gives good result, it returns true or false accordingly. However if I first log in with "Admin" Role and then try to go to a controller that requires a User role, the Authorize returns false but still the controller allows access.

protected override bool AuthorizeCore(HttpContextBase httpContext) 
    {


        if (httpContext == null) throw new ArgumentNullException("httpContext"); 

        if (httpContext.User != null)
        {
            if (httpContext.User.Identity.IsAuthenticated)
            {
                if (httpContext.User.Identity is FormsIdentity)
                {
                    FormsIdentity id = httpContext.User.Identity as FormsIdentity;
                    FormsAuthenticationTicket ticket = id.Ticket;
                    string role = ticket.UserData;

                    if (RequiredRole.Contains(role)) return true;
                }
            }
            else 
                return false;

        }
        return false;

    }

Requiredrole is a property of the class.

 [CustomAuthorize(RequiredRole = "Admin", LoginPage = "Club")]
public class UsuarioAdminController : Controller
{

above code for a controller that requires admin role.

[CustomAuthorize(RequiredRole = "User", LoginPage = "Club")]
public class HotelController : Controller
{

above code for a controller with User role. Can someone see why if Authorize returns false it allows access? Thanks

The AuthorizeCore Attribute behave as expected, it returns true or false; however the controller allows access when the AuthorizeCore method returns false.

Yes, there is more code, but I dont think it makes a differnce..here it is.

public class CustomAuthorizeAttribute: AuthorizeAttribute
{
    public string RequiredRole;
    public string LoginPage;

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    {


        if (httpContext == null) throw new ArgumentNullException("httpContext"); 

        if (httpContext.User != null)
        {
            if (httpContext.User.Identity.IsAuthenticated)
            {
                if (httpContext.User.Identity is FormsIdentity)
                {
                    FormsIdentity id = httpContext.User.Identity as FormsIdentity;
                    FormsAuthenticationTicket ticket = id.Ticket;
                    string role = ticket.UserData;

                    if (RequiredRole.Contains(role)) return true;
                }
            }
            else 
                return false;

        }
        return false;

    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {

        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var routeValues = new RouteValueDictionary();
            if (LoginPage == "Club")
            {
                routeValues["action"] = "Index";
                routeValues["controller"] = LoginPage;
                routeValues["ReturnUrl"] = filterContext.HttpContext.Request.RawUrl;
                filterContext.Result = new RedirectToRouteResult(routeValues);
            }
            else {
                routeValues["area"] = "mobile";
                routeValues["action"] = "login";
                routeValues["controller"] = LoginPage;
                routeValues["ReturnUrl"] = filterContext.HttpContext.Request.RawUrl;
                filterContext.Result = new RedirectToRouteResult(routeValues);
            }
        }

    }

}
Manuel Valle
  • 297
  • 8
  • 18

1 Answers1

1

I found the answer to this particular situation and I am sharing my findings. When a request was properly unauthorized it was handled by the

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)

method. Inside that method I was checking first if the user is not authenticated. For the first request it works properly sending the user to the appropriate log in page, But now if you try to navigate to another page that requires a different role, because you are already authenticated it wont go inside the redirect and will allow access to the control. So by removing the !IsAuthenticated if at the beginning, now all unauthorized request is properly sent to the correct login page...

Manuel Valle
  • 297
  • 8
  • 18