ПО промежуточного слоя OWIN в интегрированном конвейере IIS
Прабурадж Тьягараджан, Рик Андерсон
В этой статье показано, как запускать компоненты ПО промежуточного слоя OWIN (OMCs) в интегрированном конвейере IIS и как задать событие конвейера, на котором выполняется OMC. Прежде чем читать это руководство, ознакомьтесь с общими сведениями об обнаружении классов запуска проекта Katana и OWIN . Это руководство было написано РикОм Андерсоном ( @RickAndMSFT ), Крисом Россом, Прабураджем Тиагараджаном и Говардом Диерингом ( @howard_dierking ).
Хотя компоненты ПО промежуточного слоя OWIN (OMCs) в основном предназначены для работы в конвейере, не зависящем от сервера, можно запустить OMC и в интегрированном конвейере IIS (классический режим не поддерживается). OMC можно создать для работы в интегрированном конвейере IIS, установив следующий пакет из консоли диспетчера пакетов (PMC):
Install-Package Microsoft.Owin.Host.SystemWeb
Это означает, что все платформы приложений, даже те, которые еще не могут работать за пределами IIS и System.Web, могут воспользоваться существующими компонентами ПО промежуточного слоя OWIN.
Примечание
Microsoft.Owin.Security.*
Все пакеты, поставляемые с новой системой удостоверений в Visual Studio 2013 (например, файлы cookie, учетная запись Майкрософт, Google, Facebook, Twitter, токен носителя, OAuth, сервер авторизации, JWT, Azure Active Directory и службы федерации Active Directory), создаются как OMCs и могут использоваться как в локальных сценариях, так и в сценариях с размещением в IIS.
Выполнение ПО промежуточного слоя OWIN в интегрированном конвейере IIS
Для консольных приложений OWIN конвейер приложения, созданный с помощью конфигурации запуска , задается в порядке добавления компонентов с помощью IAppBuilder.Use
метода . То есть конвейер OWIN в среде выполнения Katana обрабатывает OMCs в том порядке, в который они были зарегистрированы с помощью IAppBuilder.Use
. В интегрированном конвейере IIS конвейер запросов состоит из httpModules, подписанных на предварительно определенный набор событий конвейера, например BeginRequest, AuthenticateRequest, AuthorizeRequest и т. д. Обратите внимание, что пакет nuget Microsoft.Owin.Host.SystemWeb регистрирует OwinHttpModule
. Как правило, HttpModule
регистрируется в IIS с помощью Web.config
файла, но Microsoft.Owin.Host.SystemWeb
для динамической регистрации конвейера OwinHttpModule
в IIS используется функция IIS с именем PreApplicationStartMethodAttribute
и HttpApplication.RegisterModule(Type)
.
Если сравнить OMC с httpModule в мире ASP.NET, необходимо зарегистрировать OMC для правильного предопределенного события конвейера. Например, HttpModule MyModule
будет вызываться, когда запрос приходит на этап AuthenticateRequest в конвейере:
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 Startup Class Detection.)
Создайте пустой проект веб-приложения и назовите его 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)
настраивает все ранее зарегистрированные компоненты ПО промежуточного слоя (в данном случае два компонента диагностики) для выполнения на этапе проверки подлинности конвейера. Последний компонент ПО промежуточного слоя (который отображает диагностика и отвечает на запросы) будет выполняться на ResolveCache
этапе (событие ResolveRequestCache).
Нажмите клавишу F5, чтобы запустить приложение. В окне выходных данных отображается следующее:
Current IIS event: AuthenticateRequest Msg: Middleware 1
Current IIS event: AuthenticateRequest Msg: 2nd MW
Current IIS event: ResolveRequestCache Msg: 3rd MW
Правила маркера этапа
Компоненты ПО промежуточного слоя Owin (OMC) можно настроить для запуска на следующих событиях конвейера 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,
}
По умолчанию OMCs выполняются при последнем событии (
PreHandlerExecute
). Вот почему в нашем первом примере кода отображался "PreExecuteRequestHandler".Метод можно использовать
app.UseStageMarker
для регистрации OMC для запуска ранее на любом этапе конвейера OWIN, указанном в перечисленииPipelineStage
.Конвейер 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
этапе, так как последний OMC зарегистрирован в событииAuthenticate
, иAuthenticate
событие предшествует всем остальным событиям.