ASP.NET MVC Global или BaseController ActionFilter для выполнения перед OnAuthorization - PullRequest
5 голосов
/ 15 сентября 2011

В моем приложении (ASP.NET MVC 3) у меня есть класс BaseController, который наследуют все мои контроллеры, и в этом BaseController я переопределил метод OnActionExecuting, чтобы убедиться, что переменная Session заполнена, так как мне нужен доступ к ней во всехдругие методы действия в приложении.У меня также есть собственный атрибут Authorize, который я определил, который расширяет AuthorizeAttributeClass.В этом атрибуте я перезаписываю OnAuthorization, чтобы проверить ту же переменную Session, которую я загружаю в методе BaseController OnActionExecuting, чтобы узнать, следует ли разрешить пользователю продолжить.

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

}

Атрибут Custom Authorize

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 OnActionExecuting запускается ПОСЛЕ метода OnAuthorization в моем атрибуте AuthorizeByPermission, и мне нужно, чтобы он был другим способом, так как BaseController должен заполнять переменную Session, если она не 't прежде чем атрибут авторизации попытается получить к нему доступ.

По сути, мне нужно найти способ иметь метод базового класса или глобальный фильтр, который можно зарегистрировать для запуска до запуска метода OnAuthorization.Любые идеи о том, как это сделать?

Я попытался зарегистрировать GlobalFilter для загрузки переменной сеанса и установить для его свойства Order значение ниже, чем атрибут AuthorizeByPermission, но, похоже, это тоже не сработало.

Я также пытался переопределить метод Execute в BaseController, который фактически срабатывал до настраиваемого атрибута авторизации, но проблема заключалась в том, что у меня не было доступа к filterContext, что позволило мне перенаправить пользователя на страницу входа, если мыне удалось загрузить переменную сеанса.

Согласно комментарию bmosh, я попытался превратить мой метод BaseController OnActionExecuting в отдельный фильтр и украсить BaseController с этим атрибутом с более низким порядковым номером, чем атрибут AuthorizeByPermission, но он все еще не 't работать.

[FilterIWantToFireFirst(Order = 1)]
public class BaseController : Controller
{

}

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

Даже с указанными выше настройками сначала запускается атрибут AuthorizeByPermission.

Есть идеи?

1 Ответ

4 голосов
/ 11 октября 2011

Вы можете попробовать переопределить OnAuthorization вместо OnActionExecuting в вашем базовом контроллере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...