2009-12-08 2 views
1

У меня есть HTTPModule, который защищает доступ к страницам на основе ролей (мне нужно переопределить некоторую безопасность в некоторый код, который мы приобрели).Почему AcquireRequestState в моем HTTPModule не срабатывает _sometimes_?

Я заметил, что в одном случае он не срабатывает на сервере Server.Transfer.

Вот фрагмент кода:

 ' move to target page 
    Select Case eTransferMethod 
     Case TargetPageTransferMethod.Redirect 
      Page.Response.Redirect(strPage, False) 
     Case TargetPageTransferMethod.Transfer 
      Context.Handler = Me 
      Page.Server.Transfer(strPage) 
     Case TargetPageTransferMethod.None 
      ' Do nothing 
    End Select 

Дело, что я говорю здесь случай TargetPageTransferMethod.Transfer. Страница будет .aspx.

Теперь я знаю, что AcquireRequestState уволен на других вызовах Server.Transfer в этом коде. Фактически, он запускается после обратной передачи при нажатии кнопки на перенесенной странице. По иронии судьбы мой код безопасности обходит при передаче на эту страницу, но запрещает доступ к обратной передаче, когда нажата кнопка отмены этой страницы! : eek:

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

В основном я спрашиваю 'Что может привести к тому, что событие AcquireRequestState в HTTPModule не будет срабатывать при вызове Server.Transfer? '

ответ

3

Способ обойти это создать пользовательский HttpHandler, который наследует класс System.Web.UI.PageHandlerFactory.

Вы можете затем переопределить метод GetHandler, который вызывается всякий раз, когда создается экземпляр страницы, как на Response.Redirect, так и на Server.Transfer.

Зарегистрируйте этот новый обработчик, чтобы использовать расширение «* .aspx», и все страницы будут автоматически использовать новый обработчик. Это позволяет выполнять пользовательскую авторизацию на сервере Server.Transfer, а также использовать инфраструктуру инъекции зависимостей (например, MS Unity).

0

Я могу понять, что его вызывают на почте, так как это другой запрос от клиента, но Server.Transfer не инициирует новый запрос, он передает исполнение с одной страницы на другую.

Поскольку событие AcquireRequestState запущено ", когда ASP.NET получает текущее состояние (например, состояние сеанса), связанное с текущим запросом" - это будет происходить при первоначальном запросе из браузера, но не на сервер, поскольку сервер не получил другого запроса, вы просто просите его обработать другую страницу.

Ключевой комментарий это один из HttpServerUtility.Transfer documentation:

ASP.NET не проверяет, что текущий пользователь имеет право просматривать ресурс, подаваемое методом передачи. Хотя логика авторизации и аутентификации ASP.NET выполняется до вызова обработчика исходного ресурса, ASP.NET напрямую вызывает обработчик, указанный методом Transfer, и не перезапускает логику аутентификации и авторизации для нового ресурса. Если для политики безопасности вашего приложения требуется, чтобы клиенты имели соответствующее разрешение для доступа к ресурсу, приложение должно принудительно выполнить повторную авторизацию или предоставить настраиваемый механизм контроля доступа.

+0

Да, вы правы. Я только что проверил свое первоначальное доказательство места тестирования концепции, и я могу только предположить, что был пьян, когда делал начальные тесты. :( Нужно переосмыслить эту идею использования HTTPModule. – user129345

0

Server.Transfer не перерабатывает весь HTTP-конвейер для целевой страницы. Он просто вызывает HttpHandler целевой страницы. Из-за этого вы не должны видеть, что какие-либо из ранних случаев применения увольняются.

+0

Yup, spot on, d'oh! См. Приведенный выше комментарий. :( – user129345

+0

Немного смущен, но я собираюсь сделать ответ Спунера на вопрос, потому что он предложил решение. Спасибо за головы, хотя! – user129345