ASP.. NET MVC Global或BaseController ActionFilter在OnAuthoriza

本文关键字:ActionFilter OnAuthoriza BaseController NET MVC Global ASP | 更新日期: 2023-09-27 18:08:37

. NET MVC 3)我有一个BaseController类,所有我的控制器继承和在该BaseController中,我已经覆盖了onactionexecution方法来检查,以确保一个会话变量填充,因为我需要访问在应用程序中的所有其他动作方法。我还定义了一个定制的Authorize属性,它扩展了AuthorizeAttributeClass。在该属性中,我重写OnAuthorization以检查我在BaseController onactionexecution方法中加载的相同会话变量,以查看是否应该允许用户继续。

BaseController

public class BaseController : Controller
{
    private ISessionUserService sessionUserService;
    public BaseController(ISessionUserService sessionUserService)
    {
        this.sessionUserService = sessionUserService;            
    }
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
        if (User != null && User.Identity.IsAuthenticated && this.sessionUserService.Current == null)
        {                     
            this.sessionUserService.Start(accountID, User.Identity.Name);                                                                           
            // If we weren't successful in reloading the SessionUser
            // variable, redirect the user to the Sign In view
            if (this.sessionUserService.Current == null)
            {                  
                filterContext.Result = new RedirectResult(Url.Action("SignIn", "Access", new { area = string.Empty }));
                return;
            }
        }
    }
}

自定义授权属性

public class AuthorizeByPermission : AuthorizeAttribute
{        
    public Permission[] Permissions { get; set; }
    public AuthorizeByPermission(params Permission[] permissions)
    {
        this.Permissions = permissions;
    }
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        SessionUser sessionUser = filterContext.HttpContext.Session.Get<SessionUser>();
        if (sessionUser.HasPermission(Permissions))
            return;
        filterContext.Result = new HttpUnauthorizedResult();
    }
}

问题是,BaseController onactionexecution方法在我的AuthorizeByPermission属性中的OnAuthorization方法后触发,我需要它是另一种方式,因为BaseController需要填充会话变量,如果它在授权属性尝试访问它之前不存在。

基本上,我需要找到一种方法来拥有一个基类方法或一个全局过滤器,可以在OnAuthorization方法触发之前注册发生。有什么办法吗?

我已经尝试注册一个GlobalFilter来加载会话变量,并将其Order属性设置为低于AuthorizeByPermission属性,但这似乎也不起作用。

我还尝试在BaseController中重写Execute方法,并且实际上在自定义授权属性之前触发,但问题是我没有访问filterContext,如果我们无法加载会话变量,它允许我将用户重定向到SignIn页面。

根据bmosh的评论,我试着把我的BaseController onactionexecution方法变成一个单独的过滤器,并用比AuthorizeByPermission属性更低的顺序编号来装饰BaseController,但它仍然没有工作。

[FilterIWantToFireFirst(Order = 1)]
public class BaseController : Controller
{
}
public class AnotherController : BaseController
{
     [AuthorizeByPermission(Permission.Add, Order = 2)]
     public ActionResult SomeActionMethod() 
     {
     }
}

即使使用上述设置,AuthorizeByPermission属性也会首先触发。

任何想法?

ASP.. NET MVC Global或BaseController ActionFilter在OnAuthoriza

你可以尝试在你的基础控制器中重写OnAuthorization而不是onactionexecution。