.net mvc 授权与 OnAuthorization

.net mvc authorization with OnAuthorization

在我的基本控制器中,我有一个 OnAuthorization 事件处理程序,在我的控制器中,我的处理程序有时有 [Authorize],有时没有。这些控制器继承自基本控制器。

我期望的是在实际需要授权时触发 OnAuthorization(具有 [Authorize] 的方法或控制器。

情况并非如此,每个方法都会触发 OnAuthorization。

有没有办法防止这种情况发生或检测 method/class 没有 [Authorize] 属性?

目前我只想授权 5 个或 25 个左右的处理程序,因此最好有一个方法来处理它而不必更改所有控制器。

您可以使用 [AllowAnonymous]

排除对特定 action/method 的授权

示例:

[AllowAnonymous] public ActionResult MyAction() { }

参见 Filtering in MVC

MVC控制器OnAuthorization方法起作用的原因是因为控制器class实现了IAuthorizationFilter并且MVC使用ControllerInstanceFilterProvider将所有控制器注册为全局过滤器。

全局授权过滤器 运行 每个 请求。由您决定他们是否有资格进行授权检查。如果想在AuthorizeAttribute不存在的情况下获得运行的权限,需要添加条件判断AuthorizeAttribute是否存在,如果存在则跳过自定义授权检查.

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);
}

默认情况下不会发生这种情况的原因是 AuthorizeAttributeIAuthorizationFilter 与控制器实例不同的实例 AuthorizeAttribute 既是 IAuthorizationFitler 又是 FilterAttribute。当你把它放在一个动作方法上时,它 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,所以它对每个请求都是 运行。这 2 个授权过滤器完全不知道对方。

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 for further explanation and an example.