Конструктор конвейера ASP.NET MVC, вызываемый перед аутентификацией

У меня есть приложение ASP.NET MVC с контроллером, который выглядит примерно так:

[Authorize]
public class MyController : Controller
{
IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
   this.myRepository = myRepository;
}

...
}

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

Я мог бы проверить входящий запрос в конструкторе и поручительство, если пользователь не авторизован, но я использую IOC (Windsor), который делает это немного сложнее, мой репозиторий будет инициализирован независимо от того, хранят ли я экземпляр, поэтому я бы оставил проверку подлинности в каждом конструкторе репозитория. Есть ли простой способ заставить .NET MVC аутентифицировать пользователя перед вызовом конструктора? Я думаю что-то вроде добавления [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] к контроллеру, но может быть еще лучше.

EDIT:

Хорошо, не слишком доволен этим, но показ должен продолжаться. Я не могу отложить инициализацию репозитория до некоторого более позднего момента времени внутри контроллера. Когда ваш контроллер использует IOC, как в моем примере, вы получаете уже созданную реализацию интерфейса вашего репозитория в момент создания экземпляра контроллера. Если бы я контролировал созданный репозиторий, я мог бы просто просто вызвать IsAuthenticated, не нуждаясь в новом методе. Чтобы взять под контроль инициализацию репозитория, вам придется реализовать некоторую ленивую/позднюю инициализацию в самом репозитории в каждой реализации. Мне не нравится это решение, потому что оно добавляет ненужную сложность и, что более важно, связь между контроллером и репозиторием. Реализация (-ы) хранилища может использоваться в других контекстах, где ленивая инициализация не имеет смысла ИМХО.

Ответы

Ответ 1

Вы можете использовать HttpModules (или HttpHandler) для аутентификации запроса ранее в конвейере.

ИЗМЕНИТЬ

С введением OWIN вы можете сконфигурировать все промежуточное ПО конвейера запроса и поставить авторизацию на любом этапе, который вы хотите. Та же идея, что и выше, но немного проще реализовать.

Ответ 2

Контроллер должен быть создан до авторизации, потому что он может действовать как собственный фильтр авторизации с помощью метода OnAuthorization. Изменение этого поведения связано с заменой некоторых основных частей конвейера mvc. Есть ли особая причина, почему вы считаете, что AuthorizedAttribute может не выполнять свою работу?

Другой вариант, который вы могли бы рассмотреть, - инициализировать ваш репозиторий в OnActionExecuting вашего метода контроллера, а не в конструкторе.

Ответ 3

Павел

создание экземпляра контроллера - это много процессов перед любыми действиями на вызываемом контроллере. даже если бы злоумышленник попытался извлечь выгоду из этого промежутка времени между созданием экземпляра и экраном входа в систему, действие контроллера могло бы работать только в том случае, если действие имело право на это, т.е. я предполагаю, что ваши действия или контроллер все на них есть атрибут [Authorize].

Я не думаю, что вам нужно слишком много беспокоиться об этом и спокойно отдохнуть, а я понимаю ваше очевидное любопытство.

Ответ 4

В терминах DOS-атак это действительно не имеет значения - после первого попадания, которое во время разработки обнаруживается много, создание экземпляра контроллера должно быть дешевым. Ну, если вы DDOSing самостоятельно, если конструктор выполняет фактическую работу, такую ​​как предварительный кэширование поиска базы данных.,.