Подтвердить что ты не робот

Как "Требовать SSL" влияет на жизненный цикл приложения ASP.NET MVC?

У меня есть приложение, которое вступает в BeginRequest и EndRequest для установки и смены сеансов NHibernate следующим образом:

BeginRequest += delegate
{
    CurrentSessionContext.Bind(SessionFactory.OpenSession());
};

EndRequest += delegate
{
    var session = CurrentSessionContext.Unbind(SessionFactory);
    session.Dispose();

    Container.Release(session);
};

Это отлично работает при развертывании в IIS, пока я не проверю флажок "Требовать SSL" . Как только я это сделаю, я получаю NullReferenceException в session.Dispose().

Я еще не отлаживал это, и да, исправление тривиально, но мне просто интересно, как "Требовать SSL" влияет на жизненный цикл запроса. В этом случае сеанс не настроен на сервере?

EDIT. Чтобы уточнить, я имею в виду параметр "Требовать SSL" в конфигурации IIS для приложения, а не атрибут RequireHttps для контроллеров.

4b9b3361

Ответ 1

Это вызвало мое любопытство, поэтому я немного втянулся в него; извините за некромантию.

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

Получается, что когда "Требовать SSL" установлен и вы получаете доступ без SSL, большинство событий полностью пропущены. Первое событие для запуска - LogRequest, затем PostLogRequest, EndRequest, PreSendRequestContent и PreSendRequestHeaders (в этом порядке). Другие события не запускаются.

Итак, ваш код сбой, потому что событие BeginRequest никогда не запускалось, а делегат EndRequest пытался Dispose() что-то, что никогда не создавалось.

Мне интересно узнать, почему IIS ведет себя так. Я подозреваю, что причина в том, что IIS по-прежнему необходимо регистрировать недопустимые попытки подключения, а также отправлять контент и заголовки, даже если запрашиваемому ресурсу требуется SSL. В конце концов, что-то должно создать эту дружескую "запретную" страницу. Я не знаю, почему EndRequest вызывается вообще, когда они не беспокоили вызов BeginRequest; Я угадываю там некоторый код очистки IIS/ASP, который зависит от него.

Это поведение зависит от того, работает ли пул приложений в режиме "Интегрированный" или "Классический". В режиме "Классический" события ASP.NET запускают "промежуточные" события IIS PreRequestHandlerExecute и PostRequestHandlerExecute. Вы не сказали, что вы бежали, но он должен быть интегрирован; в противном случае вы бы увидели поведение, которое ожидали, т.е. ни один из ваших кодов не выполнил бы вообще.

Интересно, что если вы попытаетесь подписаться на события LogRequest, PostLogRequest или MapRequestHandler, когда в классическом режиме вы получаете исключение во время выполнения; они только "имеют смысл" в контексте интегрированного конвейера.