Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Charger des composants OWIN dans le pipeline IIS

Poster un commentaire

Le pipeline ASP.NET supporte de longue date l’authentification par formulaire, mais pas l’authentification par claims.

Cette fonctionnalité est précisément une des nouveautés du framework MVC 5 qui est hébergé dans le pipeline ASP.NET. Ce que vous devez savoir est que le composant qui  apporte cela est en réalité un composant OWIN.

Ainsi il est possible d’héberger un middleware dans le pipeline ASP.NET. C’est précisément la fonctionnalité que nous allons étudier dans cet article.

 

Un petit rappel sera nécessaire pour la suite:

Le pipeline ASP.NET est très différent du pipeline OWIN. Il s’agit en fait d’une série de modules, c’est à dire de classes qui implémentent IHttpModule. Chaque module est rattaché à un événement particulier du cycle de vie du pipeline par la méthode Init de l’interface.

Il est important dès maintenant de noter l’ordre dans lequel les événements se produisent:

  1. Authenticate
  2. PostAuthenticate
  3. Authorize
  4. PostAuthorize
  5. ResolveCache
  6. PostResolveCache
  7. MapHandler
  8. PostMapHandler
  9. AcquireState
  10. PostAcquireState
  11. PreHandlerExecute

 

Si vous avez besoin de vous rafraîchir la mémoire sur le cycle de vie de ce pipeline, lisez l’article suivant:

https://amethyste16.wordpress.com/2014/04/08/cycle-de-vie-de-quelques-pipelines-web/

 

Important: Le portage des middleware dans le pipeline ASP.NET/IIS n’est supporté que dans le pipeline intégré (pas le classique, celui de IIS 6).

Faisons tout de suite une démonstration inspirée de celle trouvée ici:

http://www.asp.net/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

 

  • Créer un projet web vide, on va l’appeler MonProjet
  • installer le package Nuget:
    Install-Package Microsoft.Owin.Host.SystemWeb

Ce package est essentiel, c’est lui qui fait le travail!

  • Création de la classe Startup:
  • on ajoute le middleware
private void PrintCurrentIntegratedPipelineStage(IOwinContext context, string msg)
{
    var currentIntegratedpipelineStage = HttpContext.Current.CurrentNotification;
    TextWriter writer = context.Get<TextWriter>("host.TraceOutput");
    writer.WriteLine("Evénement IIS en cours: " + currentIntegratedpipelineStage + " Message: " + msg);
}

Notez la propriété CurrentNotification qui indique le nom de l’événement courant. C’est cette information que nous allons afficher avec un petit message qui servira surtout de repère.

L’affichage aura lieu dans la console de sortie que l’on récupère avec Get<>.

  • On ajoute la méthode Configuration

public void Configuration(IAppBuilder app)
{
    app.Use((context, next) =>
    {
        PrintCurrentIntegratedPipelineStage(context, "Middleware 1");
        return next.Invoke();
    });

    app.Use((context, next) =>
    {
        PrintCurrentIntegratedPipelineStage(context, "Middleware 2");
        return next.Invoke();
    });

    app.Run(context =>
   {
      PrintCurrentIntegratedPipelineStage(context, "Middleware 3");
      return context.Response.WriteAsync("Hello world");
    });
}

  • Lancer l’application depuis VS

Ce n’est pas l’affichage Html qui nous intéresse, mais celui dans la console de sortie:

17-04-2014 09-11-50

 

On constate deux choses:

  • les middleware ont bien été intégré
  • par défaut ils sont déclenchés lors de l’événement PreExecuteRequestHandler, c’est à dire tout au bout du pipeline Asp.Net

Jusque là ce n’est pas bien intéressant.

Nous pouvons en fait positionner les pipeline où l’on veut à l’aide des stage markers (marqueurs d’étape). C’est plus facile avec une démo:


public void Configuration(IAppBuilder app)
{
    app.Use((context, next) =>
    {
        PrintCurrentIntegratedPipelineStage(context, "Middleware 1");
        return next.Invoke();
    });

    app.Use((context, next) =>
    {
        PrintCurrentIntegratedPipelineStage(context, "Middleware 2");
        return next.Invoke();
    });

    // stage marker
    app.UseStageMarker(PipelineStage.Authenticate);

    app.Run(context =>
    {
        PrintCurrentIntegratedPipelineStage(context, "Middleware 3");
        return context.Response.WriteAsync("Hello world");
    });

    // stage marker
    app.UseStageMarker(PipelineStage.ResolveCache);
}

Et cette fois:

17-04-2014 09-20-58

Quelles sont les constatations:

  • les stages markers se positionne APRES les middlewares concernés
  • Ca marche!

Faisons quelques expériences.

On modifie le premier stage markers de cette façon:


app.UseStageMarker(PipelineStage.Authenticate);

app.UseStageMarker(PipelineStage.MapHandler);

On récupère ceci:

17-04-2014 09-20-58

La conclusion est que pour un middleware donné, seul le premier stage marker positionné est pris en compte.

On pourrait aussi inverser les deux stage markers du premier exemple. On aura donc la séquence:


...

app.UseStageMarker(PipelineStage.ResolveCache);

...

app.UseStageMarker(PipelineStage.Authenticate);

 

17-04-2014 09-27-06

Ce n’est peut être pas ce à quoi on s’attendais.

Souvenons nous de l’ordre de passage des événements:

  1. Authenticate
  2. PostAuthenticate
  3. Authorize
  4. PostAuthorize
  5. ResolveCache
  6. PostResolveCache
  7. MapHandler
  8. PostMapHandler
  9. AcquireState
  10. PostAcquireState
  11. PreHandlerExecute

Authenticate est donc déclenché AVANT ResolveCache.

On en conclut que les stages markers doivent respecter l’ordre des événements.

 

Il est donc bien important de comprendre une chose. Par défaut les middlewares sont rattachés à l’événement PreHandlerExecute. Les stages markers ont pour fonction de les déclencher plus tôt dans le pipeline. Donc on ne va que dans un sens.

C’est ce qui explique que dans notre test, les composants se déclenchent dans AuthenticateRequest. Le stage marker signifie « lance le, mais pas plus tard que l’étape XXX« .

Puisque Authenticate arrive avant ResolveCache, le pipeline déclenche les middleware qui précèdent lors de l’tape AuthenticateRequest.

Conclusions

Nous avons vu qu’il est parfaitement possible d’intégrer dans le pipeline intégré de IIS des middleware OWIN. Puisque l’on est dans un pipeline ASP.NET et non pas Owin il ne suffit pas de chaîner les composants dans le bon ordre, on doit également les affecter à un événement standard du pipeline.

C’est ce que l’on fait avec les stage markers.

 

 

 

 

 

 

 

 

 

 

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s