IIS 整合管線中的 OWIN 中介軟體
作者 :Praburaj Thjan、 Rick Anderson
本文說明如何在 IIS 整合管線中執行 OWIN 中介軟體元件 (OMC) ,以及如何設定 OMC 執行的管線事件。 閱讀本教學課程之前,您應該先檢閱 Project Katana 和 OWIN 啟動類別偵測 的概觀。 本教學課程是由 Rick Anderson ( @RickAndMSFT @RickAndMSFT 、Chris ) 、Praburaj Th (和 Howard Dierking ( @howard_dierking ) 所撰寫。
雖然OWIN中介軟體元件 (OMC) 主要是設計成在伺服器無關的管線中執行,但不支援在 IIS 整合管線中執行 OMC, (傳統模式不支援) 。 您可以從套件管理員主控台安裝下列套件, (PMC) ,讓 OMC 在 IIS 整合管線中運作:
Install-Package Microsoft.Owin.Host.SystemWeb
這表示即使尚未能夠在 IIS 和 System.Web 外部執行的所有應用程式架構,都可以受益于現有的 OWIN 中介軟體元件。
注意
Microsoft.Owin.Security.*
Visual Studio 2013 (中以新身分識別系統傳送的所有套件,例如:Cookie、Microsoft 帳戶、Google、Facebook、Twitter、持有人權杖、OAuth、授權伺服器、JWT、Azure Active directory 和 Active Directory 同盟服務) 撰寫為 OMC,並可用於自我裝載和 IIS 裝載的案例中。
OWIN 中介軟體如何在 IIS 整合式管線中執行
針對 OWIN 主控台應用程式,使用 啟動組態 建置的應用程式管線是由使用 IAppBuilder.Use
方法新增元件的順序來設定。 也就是說, Katana 執行時間中的 OWIN 管線會依使用 IAppBuilder.Use
註冊的順序來處理 OMC。 在 IIS 整合管線中,要求管線是由訂閱預先定義之管線事件的 HttpModules 所組成,例如 BeginRequest、 AuthenticateRequest、 AuthorizeRequest等。請注意, Microsoft.Owin.Host.SystemWeb nuget 套件會 OwinHttpModule
註冊 。 一般而言, HttpModule
會透過 Web.config
檔案在 IIS 中註冊,但 Microsoft.Owin.Host.SystemWeb
使用稱為 PreApplicationStartMethodAttribute
的 IIS 功能,並 HttpApplication.RegisterModule(Type)
動態向 IIS 管線註冊 OwinHttpModule
。
如果我們比較 OMC 與 ASP.NET 世界中 HttpModule 的 OMC,則必須向正確的預先定義管線事件註冊 OMC。 例如,當要求進入管線中的AuthenticateRequest階段時,就會叫用 HttpModule MyModule
:
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.
}
}
為了讓 OMC 參與這個相同的事件型執行順序, Katana 執行時間程式碼會掃描 啟動 設定,並將每個中介軟體元件訂閱至整合式管線事件。 例如,下列 OMC 和註冊程式碼可讓您查看中介軟體元件的預設事件註冊。 (如需建立 OWIN 啟動類別的詳細指示,請參閱 OWIN 啟動類別偵測.)
建立空的 Web 應用程式專案,並將其命名為 owin2。
從 [套件管理員主控台] (PMC) ,執行下列命令:
Install-Package Microsoft.Owin.Host.SystemWeb
新增 ,
OWIN Startup Class
並將其命名為Startup
。 將產生的程式碼取代為下列 (變更會反白顯示) :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); } } }
按 F5 以執行應用程式。
啟動組態會設定具有三個中間件元件的管線,前兩個顯示診斷資訊和最後一個回應事件 (,也會顯示診斷資訊) 。 方法 PrintCurrentIntegratedPipelineStage
會顯示叫用這個中介軟體的整合式管線事件,以及一則訊息。 輸出視窗會顯示下列內容:
Current IIS event: PreExecuteRequestHandler Msg: Middleware 1
Current IIS event: PreExecuteRequestHandler Msg: 2nd MW
Current IIS event: PreExecuteRequestHandler Msg: 3rd MW
Katana 執行時間預設會將每個 OWIN 中介軟體元件對應至 PreExecuteRequestHandler ,其對應于 IIS 管線事件 PreRequestHandlerExecute。
階段標記
您可以使用擴充方法,將 OMC 標示為在管線 IAppBuilder UseStageMarker()
的特定階段執行。 若要在特定階段執行一組中介軟體元件,請在註冊期間于最後一個元件之後插入階段標記。 您可以執行中介軟體的管線階段有規則,而且順序元件必須執行 (本教學課程稍後會說明這些規則) 。 將 方法新增至 Configuration
程式 UseStageMarker
代碼,如下所示:
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);
}
呼叫會 app.UseStageMarker(PipelineStage.Authenticate)
設定先前註冊的所有中介軟體元件 (在此案例中,我們的兩個診斷元件) 在管線的驗證階段上執行。 最後一個中介軟體元件 (顯示診斷和回應要求,) 將在ResolveRequestCache事件) (階段執行 ResolveCache
。
按 F5 以執行應用程式。輸出視窗會顯示下列內容:
Current IIS event: AuthenticateRequest Msg: Middleware 1
Current IIS event: AuthenticateRequest Msg: 2nd MW
Current IIS event: ResolveRequestCache Msg: 3rd MW
階段標記規則
OMC) (Owin 中介軟體元件可以設定為在下列 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,
}
根據預設,OMC 會在最後一個事件 (
PreHandlerExecute
) 執行。 這就是我們的第一個範例程式碼顯示 「PreExecuteRequestHandler」 的原因。您可以使用
app.UseStageMarker
方法,在列舉中列出的PipelineStage
OWIN 管線的任何階段註冊 OMC,以便稍早執行。OWIN 管線和 IIS 管線已排序,因此對
app.UseStageMarker
的呼叫必須依序排列。 您無法將事件處理常式設定為之前向 註冊app.UseStageMarker
的最後一個事件的事件。 例如,在呼叫 之後 :app.UseStageMarker(PipelineStage.Authorize);
對
app.UseStageMarker
傳遞Authenticate
或PostAuthenticate
不會接受的呼叫,而且不會擲回例外狀況。 OMC 會在最新的階段執行,預設為PreHandlerExecute
。 階段標記可用來讓它們稍早執行。 如果您依序指定階段標記,我們會四捨五入到先前的標記。 換句話說,新增階段標記會顯示「不晚于階段 X 執行」。 OMC 會在 OWIN 管線中新增的最早階段標記上執行。呼叫的最早階段
app.UseStageMarker
。 例如,如果您從先前的app.UseStageMarker
範例切換呼叫順序: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); }
輸出視窗會顯示:
Current IIS event: AuthenticateRequest Msg: Middleware 1 Current IIS event: AuthenticateRequest Msg: 2nd MW Current IIS event: AuthenticateRequest Msg: 3rd MW
OMC 全都會在階段中
AuthenticateRequest
執行,因為最後一Authenticate
個向 事件註冊的 OMC,而Authenticate
事件會位於所有其他事件之前。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應