Почему защищать маршруты MVC - плохая практика?

MSDN довольно четко описывает маршрутизацию и безопасность MVC:

Единственный поддерживаемый способ защиты приложения MVC - это применить атрибут AuthorizeAttribute к каждому контроллеру и использовать атрибут AllowAnonymousAttribute для действий входа и регистрации.

Однако я рассматриваю следующий подход:

Во-первых, я реализовал настраиваемую фабрику контроллеров, которая выполняет проверки безопасности на основе информации, поступающей от нашей настраиваемой службы STS.

Помимо другой информации, маркер, выпущенный STS, содержит утверждения, описывающие все маршруты MVC, к которым пользователю разрешен доступ.

Затем я проверяю утверждения пользователей в методе CreateController:

public class SecuredControllerFactory : IControllerFactory
{
   public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        ...
        bool isAuthorized = principal.HasRequiredRight(verb, ressource);
        ...
    }
}

Таким образом, мы можем централизованно настраивать и обновлять правила безопасности без повторного развертывания наших приложений. Более того, это соответствует идее «соглашение важнее конфигурации».

Что-то не так с этим подходом? Я не понимаю, почему это считается плохой практикой? Может ли кто-нибудь продемонстрировать конкретную проблему безопасности с этим?


person rlesias    schedule 08.10.2013    source источник
comment
Вам нужно будет описать свой собственный STS, чтобы сделать это разумным ...   -  person Joe Ratzer    schedule 08.10.2013


Ответы (1)


Думаю, это плохая практика, потому что она нарушает принцип единой ответственности внутри фабрики контроллеров. Единственная ответственность фабрики контроллеров должна заключаться в выборе и создании экземпляров контроллеров.

Я бы поставил под сомнение вашу причину использования подхода фабрики контроллеров:

Таким образом, мы можем централизованно настраивать и обновлять правила безопасности без повторного развертывания наших приложений.

Это допустимый оператор, если вы используете стандартный AuthorizeAttribute, который определяет разрешенных пользователей / роли в коде.

Однако рекомендуемый подход состоит в том, чтобы унаследовать от AuthorizeAttribute и реализовать логику правил безопасности в производном классе, переопределив защищенный метод AuthorizeCore(). Например, он может искать разрешения в базе данных, чтобы вы могли динамически изменять их во время выполнения.

Это также позволяет вам реализовать настраиваемую логику, которая вызывается при сбое проверки авторизации (метод HandleUnauthorizedrequest()), что, по-видимому, является тем, что вы должны делать в своей фабрике настраиваемых контроллеров при сбое логики авторизации (например, перенаправление на страницу входа или страницу ошибки. ?)

Таким образом, вы получаете возможность изменять свои правила безопасности и управлять ими централизованно без повторного развертывания всего приложения и не нарушая единственной ответственности ControllerFactory

ThinkTexture обеспечивает хорошую реализацию в своей структуре модели идентичности, как описано здесь.

http://leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/

Это позволяет вам указать ресурс / действие и инкапсулировать логику авторизации в пользовательский ClaimsAuthorizationManager обычным способом WIF. Если вы не укажете ресурс и действие явно в атрибуте, платформа получит значения из текущего HttpActionContext, что хорошо.

person Mike Goodwin    schedule 08.10.2013
comment
При использовании решения на основе атрибутов нам все еще нужно повторно развернуть, если существующий незащищенный контроллер необходимо защитить в следующей версии, не так ли? - person rlesias; 08.10.2013
comment
Да, но у вас не должно быть незащищенных контроллеров как таковых. Вы всегда выполняете проверку авторизации, и решение о том, защищена она или нет, инкапсулируется в логике атрибута (или, например, в мягких правилах, таких как БД). - person Mike Goodwin; 08.10.2013
comment
В этом есть смысл, мне нравится аргумент единственной ответственности. Если я выберу решение Attribute, не видите ли вы каких-либо неудобств в использовании маршрутов MVC в качестве защищаемых ресурсов? Я имею в виду сделать что-то вроде этого: Authorize("/Person/Administration", "Administrators") - person rlesias; 08.10.2013