Как "Требуется 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(),

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

РЕДАКТИРОВАТЬ: просто чтобы уточнить, я имею в виду параметр "Требовать SSL" в конфигурации IIS для приложения, а не RequireHttps атрибут для контроллеров.

2 ответа

Решение

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

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

Оказывается, когда установлен параметр "Требовать 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 события в классическом режиме, вы получаете исключение во время выполнения; это только "имеет смысл" в контексте интегрированного конвейера.

Другие вопросы по тегам