See Filtering in MVC.
The reason why the MVC controller OnAuthorization
method functions is because the Controller class implements IAuthorizationFilter
and MVC uses the ControllerInstanceFilterProvider
to register all controllers as global filters.
Global authorization filters run on every request. It is up to you to determine whether they qualify for the authorization check or not. If you want to have the authorization run when the AuthorizeAttribute
doesn't exist, you need to add a condition to check whether the AuthorizeAttribute
exists, and skip the custom authorization check if it does.
protected override void OnAuthorization(AuthorizationContext filterContext)
{
bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AuthorizeAttribute), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthorizeAttribute), inherit: true);
if (skipAuthorization)
{
return;
}
// Do your authorization here...
base.OnAuthorization(filterContext);
}
The reason why this doesn't happen by default is that AuthorizeAttribute
is a different instance of IAuthorizationFilter
than the controller instance. AuthorizeAttribute
is both an IAuthorizationFitler
and a FilterAttribute
. When you place it on an action method, it registers with the framework in such a way that it only executes on that action method. The controller IAuthorizationFilter
on the other hand is always registered globally, so it runs on every request. These 2 authorization filters are completely unaware of each other.
On a side note, you should never use a base controller class in MVC. For cross-cutting concerns, you can use globally registered filters. This is how the OnAuthorization
method works in a controller - it is a global filter. However, you can separate the cross-cutting code into filter classes, which are more SOLID and loosely coupled from your controllers. See this answer for further explanation and an example.
public sealed class AuthorizeWithMessage : AuthorizeAttribute { }
– Spencer Sullivan Nov 19 '19 at 22:53