Update: I recently came up against this and figured out how to use the AuthorizeAttribute to do exactly as you wanted. My attribute, that verifies if the user is an administrator, works as follows:
public class AuthorizeAdminAttribute : AuthorizeAttribute
{
public bool IsValidUser { get; protected set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null) { throw new ArgumentNullException("httpContext"); }
// Make sure Forms authentication shows the user as authenticated
if (httpContext.User.Identity.IsAuthenticated == false) return false;
// Retrieve the unit of work from Windsor, and determine if the current user is an admin
var unitOfWork = Bootstrapper.WindsorContainer.Resolve<IUnitOfWork>();
var user = new UserByIdQuery(unitOfWork).WithUserId((int)Membership.GetUser().ProviderUserKey).Execute();
if (user == null)
return false;
// Otherwise the logged in user is a real user in the system
IsValidUser = true;
return user.IsAdmin;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext == null) { throw new ArgumentNullException("filterContext"); }
// If this user is a valid user but not an admin, redirect to the homepage
if (IsValidUser)
{
// Redirect them to the homepage
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{ "area", "" },
{ "action", "Index" },
{ "controller", "Home" }
});
}
else
{
// User isn't logged in, perform normal operations
base.HandleUnauthorizedRequest(filterContext);
}
}
}
Essentially you have to user the AuthorizeCore() to determine if the user is logged in, store that result, and then perform authorization for the roles in your system. Then in your HandleUnauthorizedRequest you have to figure out if the request was unauthorized because the user wasn't logged in, or if it was because they weren't authorized.
Old Answer
I accomplish using the
Authorize attribute by creating a subclass of the
AuthorizeAttribute class. So for example:
public class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null) { throw new ArgumentNullException("httpContext"); }
// Make sure Forms authentication shows the user as authenticated
if (httpContext.User.Identity.IsAuthenticated == false) return false;
// replace with whatever code you need to call to determine if the user is authorized
return IsUserAuthorized();
}
}
Now when a controller or action is called, and is decorated with [MyCustomAuthorize] it will run this code to determine if the user is authorized based on your custom logic, and if not will redirect them exactly how the [Authorize] attribute would.
I don't know if this is the best approach, but it is what I came up with.