Конструктор конвейера 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 самостоятельно, если конструктор выполняет фактическую работу, такую как предварительный кэширование поиска базы данных.,.