IIS 集成管道中的 OWIN 中间件
作者 :Praburaj Thiagarajan, Rick Anderson
本文介绍如何在 IIS 集成管道中 (OMC) 运行 OWIN 中间件组件,以及如何设置运行 OMC 的管道事件。 阅读本教程之前,应查看 Project Katana 和 OWIN 启动类检测 概述。 本教程由 Rick Anderson ( @RickAndMSFT ) 、Chris Ross、Praburaj Thiagarajan 和 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 集成管道中,请求管道由订阅了一组预定义的管道事件(例如 BeginRequest、AuthenticateRequest、AuthorizeRequest 等)的 HttpModules 组成。请注意,Microsoft.Owin.Host.SystemWeb nuget 包注册 。OwinHttpModule
通常, HttpModule
通过 Web.config
文件在 IIS 中注册,但 Microsoft.Owin.Host.SystemWeb
使用名为 PreApplicationStartMethodAttribute
的 IIS 功能,将 HttpApplication.RegisterModule(Type)
动态注册 OwinHttpModule
到 IIS 管道。
如果将 OMC 与 ASP.NET 世界中的 HttpModule 进行比较,则必须将 OMC 注册到正确的预定义管道事件。 例如,当请求到达管道中的 AuthenticateRequest 阶段时,将调用 HttpModuleMyModule
:
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()
的特定阶段执行。 若要在特定阶段运行一组中间件组件,请在注册期间设置的最后一个组件之后插入阶段标记。 在管道的哪个阶段可以执行中间件,并且组件必须运行的顺序 (规则将在教程) 后面部分介绍。 UseStageMarker
将 方法添加到代码中,Configuration
如下所示:
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
方法注册 OMC,以便更早地在枚举中列出的PipelineStage
OWIN 管道的任何阶段运行。OWIN 管道和 IIS 管道是有序的,因此对
app.UseStageMarker
的调用必须按顺序进行。 不能将事件处理程序设置为在 向 注册app.UseStageMarker
的最后一个事件之前的事件。 例如, 在调用后 :app.UseStageMarker(PipelineStage.Authorize);
不会遵循对
app.UseStageMarker
传递 或PostAuthenticate
的Authenticate
调用,并且不会引发异常。 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
阶段中运行,因为最后一个 OMC 注册到Authenticate
事件,并且事件Authenticate
先于所有其他事件。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈