Owin облегчает внедрение нового промежуточного программного обеспечения в конвейер обработки. Это можно использовать для ввода точек останова в конвейер, для проверки состояния контекста Оуина во время аутентификации.
При создании нового проекта MVC 5.1 в проект Startup.Auth.cs
добавляется файл, который настраивает конвейер Owin с промежуточным программным обеспечением для аутентификации. С помощью двух промежуточных программ для аутентификации включаются звонки на app.UseCookieAuthentication()
и app.UseExternalSignInCookie
. Также есть закомментированные разделы для аутентификации Microsoft, Twitter, Facebook и Google. В этом посте будет использоваться Google Authentication в качестве примера, а также добавлено несколько «фиктивных» промежуточных программ, которые позволяют устанавливать точки останова и проверять конвейер аутентификации.
Вставка промежуточного программного обеспечения точки останова
Промежуточное программное обеспечение выполняется в том порядке, в котором они перечислены в файле, поэтому, вставляя простое промежуточное программное обеспечение между существующими, можно проверить, как каждое промежуточное программное обеспечение взаимодействует с конвейером аутентификации.
Внедренное промежуточное программное обеспечение — это всего лишь несколько строк кода, но оно позволяет установить две точки останова: на открывающей и закрывающей скобках, что позволяет выполнять проверку до и после вызова следующего промежуточного программного обеспечения.
app.Use(async (context, next) => { await next.Invoke(); });
Я добавил некоторое промежуточное программное обеспечение для отладки и удалил неиспользованную закомментированную инициализацию промежуточного программного обеспечения. Это итоговая функция запуска, которая будет использоваться до конца этого сообщения:
public void ConfigureAuth(IAppBuilder app) { app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); app.Use(async (Context, next) => { await next.Invoke(); }); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) } }); app.Use(async (Context, next) => { await next.Invoke(); }); app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); app.Use(async (Context, next) => { await next.Invoke(); }); app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "ABC.apps.googleusercontent.com", ClientSecret = "XYZ" }); app.Use(async (Context, next) => { await next.Invoke(); }); }
Добавление точек останова позволяет проверять каждый шаг в конвейере. Вот как это выглядит, когда я только что нажал кнопку «Google» на странице входа в приложение.
Перерыв наступает сразу после вызова ExternalLogin
действия над MVC AccountController
. Мы после звонка next.Invoke()
, но перед возвращением из этого последнего «промежуточного программного обеспечения» в цепочке. ExternalLogin
Действие возвращается обычай ChallengeResult
(также найти в AccountController.cs
файле) , что при выполнении вызовов context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
. Именно этот метод устанавливает AuthenticationResponseChallenge
показанное на картинке выше.
Это важный принцип аутентификации Owin.
Компоненты не вызывают друг друга напрямую. Они помещают сообщение в
AuthenticationManager
контекст Owin, который проверяется другим промежуточным программным обеспечением в конвейере.
Перенаправление в Google
Код состояния ответа теперь 401 и AuthenticationResponseChallenge
установлен на AuthenticationManager
. Помните, что каждое промежуточное ПО Owin может проверять каждый запрос дважды; до и после вызова следующего промежуточного программного обеспечения в цепочке.
Когда промежуточное ПО аутентификации Google проверяет исходящий ответ и обнаруживает, что код состояния — 401, оно проверяет наличие AuthenticationResponseChallenge
типа «Google». В этом случае он найдет его и соответствующим образом изменит ответ. При достижении точки останова в строке 33, так выглядит ответ.
Промежуточное ПО аутентификации Google изменило исходящий ответ и стало перенаправлением на службу Google oauth.
Получение возвращаемого значения от Google
Google выполняет аутентификацию и перенаправляет пользователя обратно с информацией аутентификации в строке запроса. Шагая по коду, точки останова в строках 42 и 44 никогда не будут достигнуты. Промежуточное ПО аутентификации Google обнаружило, что оно может обработать сам запрос, и никогда не вызывало следующее промежуточное ПО в конвейере. Вместо этого точка останова в строке 33 показывает, что она изменила ответ на перенаправление 302 и установила значение AuthenticationResponseGrant
на AuthenticationManager
.
Грант имеет AuthenticationType
в ExternalCookie , что и следующий промежуточный слой в трубопроводе ищет.
Установка внешнего куки
Промежуточное программное обеспечение для проверки подлинности с помощью внешних cookie-файлов установит cookie-файл с полученным идентификатором. Файл cookie зашифрован и работает почти так же, как и файл cookie старой формы, за исключением того, что он не автоматически читается и не используется приложением.
Внешний cookie-файл используется для запоминания идентификатора, полученного от Google во время перенаправления назад к AccountController.ExternalLoginCallback()
действию.
Преобразование в локальную идентичность
Идентификационная информация, полученная от Google, является внешней идентификацией . ASP.NET Identity строится вокруг концепции локальной идентичности, которая может иметь ноль или более внешних имен входа. Когда контроллер MVC получает внешнюю идентификацию (посредством вызова AuthenticationManager.GetExternalLoginInfoAsync()
), он ищет локальный идентификатор в ASP.NET Identity и выдает AuthenticationResponseGrant
тип ApplicationCookie
. Это итоговый ответ при проверке в строке 44.
Теперь есть как AuthenticationResponseGrant
тип, так ApplicationCookie
и AuthenticationResponseRevoke
тип, ExternalCookie
чтобы избавиться от временного внешнего cookie.
Окончательный файл cookie приложения
Наконец, поставив точку останова в строке 9, можно проверить набор файлов cookie.
Внешний файл cookie удаляется, и файл cookie приложения устанавливается. Промежуточное программное обеспечение cookie приложения теперь будет находить cookie приложения при каждом запросе и расшифровывать его, десериализировать идентификацию содержащихся утверждений и устанавливать в запросе.
Комментарии
Благодаря использованию сообщений на AuthenticationManager
конвейере аутентификации чрезвычайно разобщены. Нет (почти) жестких зависимостей между различным промежуточным программным обеспечением или контроллером MVC от реального промежуточного программного обеспечения, которое выполняет аутентификацию. Насколько я могу судить, AuthenticationManager
и хранящиеся в нем сообщения не являются частью спецификации Owin, они являются частью реализации Owin в Microsoft Katana. Поэтому, если вы используете другую реализацию, не ожидайте, что что-то в этом посте будет верным для этой реализации.
Дизайн с отдельным внешним cookie-файлом позволяет добавить слой перевода и не использовать внешнюю идентификацию как таковую. Я думаю, что также возможно использовать внешнюю идентификацию напрямую — использование ExternalCookie
промежуточного программного обеспечения не является жестко запрограммированным в промежуточном программном обеспечении аутентификации. Промежуточное программное обеспечение ищет используемое промежуточное программное обеспечение для файлов cookie, и его можно напрямую установить в файл cookie приложения (если вы попытались, оставьте комментарий, чтобы сообщить мне!).
Гибкая архитектура всегда идет с каким-то наказанием. В этом случае настройка внешнего cookie требует дополнительного перенаправления, добавляя к числу перенаправлений, возникающих при нажатии кнопки входа в систему. Всего это три перенаправления без какой-либо реальной обратной связи с пользователем, что может раздражать соединения с высокой задержкой.
Подводя итог, я думаю, что дизайн хорош и легко настраивается с использованием различных промежуточных программ в разных комбинациях. Для написания собственного промежуточного программного обеспечения (о котором пойдет речь в моем следующем посте) есть еще несколько движущихся частей, которые нужно отслеживать.