2010-06-16 2 views
12

J'ai une application qui puise dans BeginRequest et EndRequest pour mettre en place et le démontage des sessions NHibernate comme ceci:Comment «Exiger SSL» affecte-t-il le cycle de vie de l'application ASP.NET MVC?

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

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

    Container.Release(session); 
}; 

Cela fonctionne bien lorsqu'il est déployé dans IIS, jusqu'à ce que je coche la case « Exiger SSL ». Une fois que je fais cela, je reçois un NullReferenceException au session.Dispose().

Je ne l'ai pas encore débogué et, oui, le correctif est trivial, mais je suis juste curieux de savoir comment "Exiger SSL" affecte le cycle de vie d'une demande. Une session n'est-elle pas configurée sur le serveur dans ces cas? : Pour clarifier, je fais référence à l'option "Exiger SSL" dans la configuration IIS pour l'application, pas à l'attribut RequireHttps pour les contrôleurs.

+0

Cherchez-vous initialement à l'application en utilisant Http qui vous dit alors d'utiliser Https? Ou ... Vous naviguez directement à l'application en utilisant Https? – Jason

+1

Je me connecte avec Http. Je m'attendais à IIS pour répondre immédiatement avec une redirection sans invoquer aucun de mon code. – Ragesh

Répondre

5

Celui-ci a piqué ma curiosité alors j'ai creusé un peu; désolé pour la nécromancie.

J'ai créé un projet simple qui câblait les notifications pour chaque événement de cycle de vie sur l'objet d'application et définissait des points d'arrêt sur chacun d'eux.

Il s'avère que lorsque "Require SSL" est défini et que vous accédez sans SSL, la plupart des événements sont complètement ignorés. Le premier événement à déclencher est LogRequest, suivi de PostLogRequest, EndRequest, PreSendRequestContent, et PreSendRequestHeaders (dans cet ordre). Aucun autre événement n'est déclenché. Votre code s'est donc écrasé parce que l'événement BeginRequest n'a jamais été déclenché et le délégué EndRequest a tenté de créer Dispose() quelque chose qui n'avait jamais été créé.

Ce qui m'intéresse, c'est de trouver pourquoi IIS se comporte comme ceci. Je suppose que la raison en est que IIS doit toujours enregistrer les tentatives de connexion non valides, ainsi que l'envoi de contenu et d'en-têtes, même si la ressource demandée nécessite SSL. Quelque chose doit générer cette page "interdite" amicale, après tout. Qu'est-ce que je ne sais pas pourquoi EndRequest est appelé du tout quand ils ne dérange pas d'appeler BeginRequest; Je suppose qu'il y a un code de nettoyage IIS/ASP qui en dépend.

Ce comportement varie selon que le pool d'applications s'exécute en mode "Integrated" ou "Classic". En mode "Classic", les événements ASP.NET se déclenchent "entre" les événements IIS PreRequestHandlerExecute et PostRequestHandlerExecute. Vous n'avez pas dit ce que vous faisiez, mais cela doit être intégré; sinon, vous auriez vu le comportement que vous attendiez, c'est-à-dire qu'aucun de vos codes n'aurait été exécuté du tout. Il est intéressant de noter que si vous essayez de vous abonner aux événements LogRequest, PostLogRequest ou MapRequestHandler en mode Classique, vous obtenez une exception d'exécution; ceux-ci n'ont de sens que dans le contexte du pipeline intégré.

+0

Bonne réponse! Merci d'avoir pris le temps de faire des recherches sur ce sujet. – Ragesh