Oprogramowanie pośredniczące OWIN w zintegrowanym potoku usług IIS

Autor: Praburaj Thiagarajan, Rick Anderson

W tym artykule pokazano, jak uruchamiać składniki oprogramowania pośredniczącego OWIN (OMC) w zintegrowanym potoku usług IIS oraz jak ustawić zdarzenie potoku, na które działa pakiet OMC. Przed przeczytaniem tego samouczka zapoznaj się z omówieniem wykrywaniaklas uruchamiania projektu Katana i OWIN. Ten samouczek został napisany przez Ricka Andersona ( @RickAndMSFT ), Chrisa Rossa, Praburaja Thiagarajana i Howarda Dierkinga ( @howard_dierking ).

Mimo że składniki oprogramowania pośredniczącego OWIN (OMC) są przeznaczone głównie do uruchamiania w potoku niezależnego od serwera, możliwe jest uruchomienie pakietu OMC w zintegrowanym potoku usług IIS (tryb klasyczny nie jest obsługiwany). OMC można wykonać w celu pracy w zintegrowanym potoku usług IIS, instalując następujący pakiet z konsoli Menedżera pakietów (PMC):

Install-Package Microsoft.Owin.Host.SystemWeb

Oznacza to, że wszystkie struktury aplikacji, nawet te, które nie są jeszcze w stanie działać poza usługami IIS i System.Web, mogą korzystać z istniejących składników oprogramowania pośredniczącego OWIN.

Uwaga

Microsoft.Owin.Security.* Wszystkie pakiety wysyłkowe z nowym systemem tożsamości w Visual Studio 2013 (na przykład: Pliki cookie, konto Microsoft, Google, Facebook, Twitter, Token nośny, OAuth, serwer autoryzacji, JWT, Azure Active Directory i usługi federacyjne Active Directory) są tworzone jako OMCs i mogą być używane zarówno w scenariuszach hostowanych samodzielnie, jak i hostowanych przez usługi IIS.

Jak oprogramowanie pośredniczące OWIN jest wykonywane w zintegrowanym potoku usług IIS

W przypadku aplikacji konsolowych OWIN potok aplikacji utworzony przy użyciu konfiguracji uruchamiania jest ustawiany w kolejności dodawania składników przy użyciu IAppBuilder.Use metody . Oznacza to, że potok OWIN w środowisku uruchomieniowym Katana przetwarza OMC w kolejności, w której zostały zarejestrowane przy użyciu polecenia IAppBuilder.Use. W zintegrowanym potoku usług IIS potok żądania składa się z modułów HttpModules subskrybowanych do wstępnie zdefiniowanego zestawu zdarzeń potoku, takich jak BeginRequest, AuthenticateRequest, AuthorizeRequest itp. Zwróć uwagę, że pakiet nuget Microsoft.Owin.Host.SystemWeb rejestruje plik OwinHttpModule. Zazwyczaj jest rejestrowany HttpModule w usługach IIS za pośrednictwem Web.config pliku, ale Microsoft.Owin.Host.SystemWeb używa funkcji usług IIS wywoływanej PreApplicationStartMethodAttribute i HttpApplication.RegisterModule(Type) do dynamicznego rejestrowania potoku OwinHttpModule usług IIS.

Jeśli porównamy OMC z modułem HttpModule na świecie ASP.NET, należy zarejestrować OMC w prawidłowym wstępnie zdefiniowanym zdarzeniem potoku. Na przykład moduł HttpModule MyModule zostanie wywołany po przejściu żądania do etapu uwierzytelnianiaRequest w potoku:

public class MyModule : IHttpModule
{
    public void Dispose()
    {
        //clean-up code here.
    }
    public void Init(HttpApplication context)
    {
        // An example of how you can handle AuthenticateRequest events.
        context.AuthenticateRequest += ctx_AuthRequest;
    }
    void ctx_AuthRequest(object sender, EventArgs e)
    {
        // Handle event.
    }
}

Aby pakiet OMC brał udział w tej samej kolejności wykonywania opartej na zdarzeniach, kod środowiska uruchomieniowego Katana skanuje za pośrednictwem konfiguracji uruchamiania i subskrybuje poszczególne składniki oprogramowania pośredniczącego do zintegrowanego zdarzenia potoku. Na przykład poniższy kod OMC i kod rejestracji umożliwia wyświetlanie domyślnej rejestracji zdarzeń składników oprogramowania pośredniczącego. (Aby uzyskać bardziej szczegółowe instrukcje dotyczące tworzenia klasy uruchamiania OWIN, zobacz Wykrywanie klas uruchamiania OWIN).

  1. Utwórz pusty projekt aplikacji internetowej i nadaj jej nazwę owin2.

  2. W konsoli Menedżera pakietów (PMC) uruchom następujące polecenie:

    Install-Package Microsoft.Owin.Host.SystemWeb
    
  3. Dodaj element i nadaj OWIN Startup Class mu Startupnazwę . Zastąp wygenerowany kod następującym kodem (wyróżnione zmiany):

    using System;
    using System.Threading.Tasks;
    using Microsoft.Owin;
    using Owin;
    using System.Web;
    using System.IO;
    using Microsoft.Owin.Extensions;
    [assembly: OwinStartup(typeof(owin2.Startup))]
    namespace owin2
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.Use((context, next) =>
                {
                    PrintCurrentIntegratedPipelineStage(context, "Middleware 1");
                    return next.Invoke();
                });
                app.Use((context, next) =>
                {
                    PrintCurrentIntegratedPipelineStage(context, "2nd MW");
                    return next.Invoke();
                }); 
                app.Run(context =>
                {
                    PrintCurrentIntegratedPipelineStage(context, "3rd MW");
                    return context.Response.WriteAsync("Hello world");
                });            
            }
            private void PrintCurrentIntegratedPipelineStage(IOwinContext context, string msg)
            {
                var currentIntegratedpipelineStage = HttpContext.Current.CurrentNotification;
                context.Get<TextWriter>("host.TraceOutput").WriteLine(
                    "Current IIS event: " + currentIntegratedpipelineStage
                    + " Msg: " + msg);
            }
        }
    }
    
  4. Naciśnij klawisz F5, aby uruchomić aplikację.

Konfiguracja uruchamiania konfiguruje potok z trzema składnikami oprogramowania pośredniczącego, pierwsze dwa wyświetla informacje diagnostyczne i ostatni odpowiada na zdarzenia (a także wyświetla informacje diagnostyczne). Metoda PrintCurrentIntegratedPipelineStage wyświetla zdarzenie zintegrowanego potoku, na które jest wywoływane to oprogramowanie pośredniczące i komunikat. W oknach wyjściowych są wyświetlane następujące elementy:

Current IIS event: PreExecuteRequestHandler Msg: Middleware 1
Current IIS event: PreExecuteRequestHandler Msg: 2nd MW
Current IIS event: PreExecuteRequestHandler Msg: 3rd MW

Środowisko uruchomieniowe Katana mapowane domyślnie każdy składnik oprogramowania pośredniczącego OWIN do preExecuteRequestHandler , który odpowiada zdarzeniu potoku USŁUG IIS PreRequestHandlerExecute.

Znaczniki etapu

OMC można oznaczyć jako wykonywane na określonych etapach potoku przy użyciu IAppBuilder UseStageMarker() metody rozszerzenia. Aby uruchomić zestaw składników oprogramowania pośredniczącego podczas określonego etapu, wstaw znacznik etapu bezpośrednio po ostatnim składniku jest ustawiony podczas rejestracji. Istnieją reguły, na którym etapie potoku można wykonać oprogramowanie pośredniczące, a składniki zamówienia muszą zostać uruchomione (reguły zostały wyjaśnione w dalszej części tego samouczka). Dodaj metodę UseStageMarker do kodu, Configuration jak pokazano poniżej:

public void Configuration(IAppBuilder app)
{
    app.Use((context, next) =>
    {
        PrintCurrentIntegratedPipelineStage(context, "Middleware 1");
        return next.Invoke();
    });
    app.Use((context, next) =>
    {
        PrintCurrentIntegratedPipelineStage(context, "2nd MW");
        return next.Invoke();
    });
    app.UseStageMarker(PipelineStage.Authenticate);
    app.Run(context =>
    {
        PrintCurrentIntegratedPipelineStage(context, "3rd MW");
        return context.Response.WriteAsync("Hello world");
    });
    app.UseStageMarker(PipelineStage.ResolveCache);
}

Wywołanie app.UseStageMarker(PipelineStage.Authenticate) konfiguruje wszystkie wcześniej zarejestrowane składniki oprogramowania pośredniczącego (w tym przypadku nasze dwa składniki diagnostyczne) do uruchomienia na etapie uwierzytelniania potoku. Ostatni składnik oprogramowania pośredniczącego (który wyświetla diagnostykę i odpowiada na żądania) zostanie uruchomiony na ResolveCache etapie (zdarzenie ResolveRequestCache ).

Naciśnij klawisz F5, aby uruchomić aplikację. W oknie danych wyjściowych są wyświetlane następujące elementy:

Current IIS event: AuthenticateRequest Msg: Middleware 1
Current IIS event: AuthenticateRequest Msg: 2nd MW
Current IIS event: ResolveRequestCache Msg: 3rd MW

Reguły znaczników etapu

Składniki oprogramowania pośredniczącego Owin (OMC) można skonfigurować do uruchamiania w następujących zdarzeniach etapu potoku OWIN:

public enum PipelineStage
{
    Authenticate = 0,
    PostAuthenticate = 1,
    Authorize = 2,
    PostAuthorize = 3,
    ResolveCache = 4,
    PostResolveCache = 5,
    MapHandler = 6,
    PostMapHandler = 7,
    AcquireState = 8,
    PostAcquireState = 9,
    PreHandlerExecute = 10,
}
  1. Domyślnie OMC działają w ostatnim zdarzeniu (PreHandlerExecute). Dlatego nasz pierwszy przykładowy kod wyświetla "PreExecuteRequestHandler".

  2. Możesz użyć app.UseStageMarker metody , aby zarejestrować OMC, aby uruchomić wcześniej, na dowolnym etapie potoku OWIN wymienionego PipelineStage w wyliczenia.

  3. Potok OWIN i potok usług IIS są uporządkowane, dlatego wywołania app.UseStageMarker muszą być w porządku. Nie można ustawić programu obsługi zdarzeń na zdarzenie, które poprzedza ostatnie zdarzenie zarejestrowane na app.UseStageMarker. Na przykład po wywołaniu:

    app.UseStageMarker(PipelineStage.Authorize);
    

    wywołania do app.UseStageMarker przekazywania Authenticate lub PostAuthenticate nie będą honorowane, a żaden wyjątek nie zostanie zgłoszony. OMCs działają na najnowszym etapie, który domyślnie to PreHandlerExecute. Znaczniki etapu służą do uruchamiania ich wcześniej. Jeśli określisz znaczniki etapu poza kolejnością, zaokrąglimy do wcześniejszego znacznika. Innymi słowy, dodanie znacznika etapu mówi "Uruchom nie później niż etap X". Uruchomienie pakietu OMC na najwcześniejszym znaczniku etapu dodanym po nim w potoku OWIN.

  4. Najwcześniejszy etap wywołań do wygrania app.UseStageMarker . Jeśli na przykład zmienisz kolejność wywołań z poprzedniego app.UseStageMarker przykładu:

    public void Configuration(IAppBuilder app)
    {
        app.Use((context, next) =>
        {
            PrintCurrentIntegratedPipelineStage(context, "Middleware 1");
            return next.Invoke();
        });
        app.Use((context, next) =>
        {
            PrintCurrentIntegratedPipelineStage(context, "2nd MW");
            return next.Invoke();
        });
        app.UseStageMarker(PipelineStage.ResolveCache);
        app.Run(context =>
        {
            PrintCurrentIntegratedPipelineStage(context, "3rd MW");
            return context.Response.WriteAsync("Hello world");
        });
        app.UseStageMarker(PipelineStage.Authenticate);
    }
    

    Zostanie wyświetlone okno danych wyjściowych:

    Current IIS event: AuthenticateRequest Msg: Middleware 1
    Current IIS event: AuthenticateRequest Msg: 2nd MW
    Current IIS event: AuthenticateRequest Msg: 3rd MW
    

    Wszystkie OMC są uruchamiane na AuthenticateRequest etapie, ponieważ ostatni pakiet OMC zarejestrowany Authenticate w zdarzeniu i Authenticate zdarzenie poprzedza wszystkie inne zdarzenia.