Пошаговое руководство. Часть 5. Безопасность ASP.NET Core на основе утверждений с использованием аутентификации приложения Azure и конечной точки службы /.auth/me
- терминология
- переменные
- Исходный код
- Откройте образец решения и опубликуйте в Azure
- Страница «Сводка безопасности», часть 1: аутентифицированный пользователь
- Аутентификация приложения Azure (простая аутентификация) HTTP-заголовки
- Убедитесь, что ваше приложение настроено для wl.basic и wl.emails
- Страница «Сводка безопасности», часть 2: конечная точка службы /.auth/me
- Заполнение утверждений пользователей с помощью специального промежуточного программного обеспечения...
- Включение нашего промежуточного программного обеспечения в ASP.NET Core
- Измените SecuritySummaryController для доступа к IUserInformation
- Убедитесь, что информация пользователя заполняется из утверждений
- Резюме
В последнее время я много работал над веб-приложениями Azure и обнаружил, что есть некоторые основные вещи, о которых трудно найти информацию. Поэтому я решил написать несколько лабораторий. Это пятый пост в серии.
Общая цель этих лабораторных занятий - научить вас создавать приложение, которое выполняется внутри веб-приложения Azure. Хотя это не так уж сложно, есть немало шагов. Эта пятая лабораторная работа возьмет наш пример приложения и преобразует его для использования аутентификации на основе утверждений. Мы также рассмотрим, как использовать конечную точку службы аутентификации приложения Azure (также называемой Easy Auth) /.auth/me для получения более подробной информации о текущем аутентифицированном пользователе.
До сих пор в этой серии лабораторных работ у вас было приложение ASP.NET Core, которое использует политики, требования и обработчики для проверки авторизации. На уровне API логика идентификации и авторизации ASP.NET Core ориентирована на идентификацию на основе утверждений. В настоящее время в нашем примере приложения не используется проверка подлинности на основе утверждений. Отказ от использования аутентификации на основе утверждений в настоящий момент нас не слишком сдерживает, но в конечном итоге мы захотим использовать аутентификацию на основе утверждений, поскольку она гораздо более гибкая и позволяет создавать большинство современных сред безопасности.
Вот ссылка на PDF-версия этой лаборатории ,
Вот лаборатории в этой серии: Лаборатория 1 , Лаборатория 2 , Лаборатория 3 , Лаборатория 4 , Лаборатория 5
терминология
Портал использует концепцию пользовательского интерфейса, которая имеет тенденцию расширяться горизонтально вправо. Каждый раз, когда вы выбираете что-то, вместо того, чтобы открывать диалоговое окно, оно создает новую панель в пользовательском интерфейсе. Эти панели называются лезвиями . Я буду ссылаться на лезвия пользовательского интерфейса в этой лаборатории.
переменные
Многие ресурсы, которые вы создадите в этой лаборатории, будут нуждаться в уникальных именах. Когда я говорю «уникальный», я имею в виду, что они должны быть уникальными для Azure, а не просто увлекательными и креативными. Поскольку я не могу знать, какие значения вам нужно выбрать, я сейчас дам вам список этих значений и позволю вам выбрать их. Я буду называть их «переменными» во всей лаборатории, а когда я буду ссылаться на них, я буду заключать их в квадратные скобки, например: {{Variable Name}}.
Имя переменнойОписаниеВаше значение
{{Имя приложения}} Это имя вашего приложения в Azure. Это в конечном итоге превратится в URL для вашего приложения. Например, если моим именем приложения является «thingy123», URL-адрес приложения, который генерирует Azure, будет https://thingy123.azurewebsites.net , {{Группа ресурсов}} Это имя группы ресурсов Azure.
{{URL-адрес службы приложений}} Это URL-адрес вашего веб-приложения. Это значение генерируется для вас Azure. https: // {{Имя приложения}}. azurewebsites.net
Исходный код
Вы можете скачать исходный код для этой лаборатории с
https://www.benday.com/labs/azure-web-app-security-2018/benday-azure-web-app-code-lab5.zip
Откройте образец решения и опубликуйте в Azure
Для этой лабораторной работы вы будете использовать простое приложение ASP.NET MVC Core, которое находится в zip-файле для лабораторной работы 5. Этот код очень прост. Это не намного больше, чем вы получили бы, если бы создали новое решение и проект ASP.NET MVC Core.
- Найдите почтовый файл для этой лаборатории.
- Распакуйте zip в папку на вашем локальном диске (например, c: \ temp \ azure-labs)
- В папке before для этой лабораторной работы откройте решение EasyAuthDemo.sln с помощью Visual Studio 2017. Когда оно откроется, вы увидите два проекта в Solution Explorer.
- Давайте удостоверимся, что веб-проект помечен как стартовый проект. В обозревателе решений щелкните правой кнопкой мыши проект EasyAuthDemo.WebUi . В контекстном меню выберите « Установить как проект запуска» .
- Опубликуйте EasyAuthDemo.WebUi на своем веб-сайте Azure, щелкнув правой кнопкой мыши -> Развернуть .
- После завершения публикации вы увидите окно браузера с вашим опубликованным веб-приложением, запущенным в Azure. Если вы не видите свое приложение, откройте браузер и перейдите к {{URL-адресу службы приложений}}.
- В строке меню веб-приложения нажмите ссылку Сводка безопасности
- Вы должны увидеть страницу, которая выглядит следующим образом.
Эта страница приложения является страницей Сводка безопасности .
Страница «Сводка безопасности», часть 1: аутентифицированный пользователь
Цель Security Summary - быстро визуализировать происходящее, связанное с безопасностью в приложении. Важно отметить, что эта страница не требует, чтобы вы вошли в систему, и это полезно, потому что, как разработчик, вы должны видеть, что происходит с безопасностью вашего приложения как для аутентифицированных, так и для не аутентифицированных пользователей.
В настоящее время эта страница реализована лишь частично. Мы реализуем все недостающие вещи в этой лаборатории. Интерфейс «Сводка безопасности» разделен на разделы: «Информация о пользователе», «Сводка заявок», «Сводка заголовка» и «Сводка cookie».
- Информация о пользователе еще не реализована.
- Сводка утверждений реализуется самим приложением, не настроенным на использование утверждений, поэтому раздел пользовательского интерфейса пуст.
- Сводка заголовка полностью реализована и показывает вам все заголовки и значения заголовков, которые были в последнем HTTP-запросе.
- Сводка файлов cookie реализована и показывает вам все файлы cookie, которые были в последнем HTTP-запросе.
Давайте пройдемся по странице «Сводка безопасности».
- В верхней части страницы «Сводка безопасности» нажмите « Вход в систему», используя свою учетную запись Microsoft, и вернитесь на страницу « Сводка безопасности» .
- Найдите раздел « Сводка заголовка » пользовательского интерфейса. Прокрутите вниз значения заголовков, пока не дойдете до значений, начинающихся с « X-MS-» . Эти заголовки должны быть выделены жирным шрифтом.
Аутентификация приложения Azure (простая аутентификация) HTTP-заголовки
Вы должны увидеть несколько заголовков, выделенных жирным шрифтом, таких как X-MS-CLIENT-PRINCIPAL-NAME, X-MS-CLIENT-PRINCIPAL-IDP и X-MS-TOKEN-MICROSOFTACCOUNT-EXPIRES-ON . Эти заголовки внедряются в ваш HTTP-запрос с помощью безопасности аутентификации приложения Azure.
- X-MS-CLIENT-PRINCIPAL-NAME содержит удобочитаемое имя текущего пользователя или имя текущего пользователя.
- X-MS-CLIENT-PRINCIPAL-IDP содержит имя провайдера идентификации, который использовался для аутентификации этого пользователя. В данном случае это микро- учетная запись, означающая, что мы использовали учетную запись Microsoft (MSA) для создания этой сессии.
- X-MS-TOKEN-MICROSOFTACCOUNT-EXPIRES-ON сообщает нам, когда истечет срок действия маркера безопасности.
Значение, которое вы видите для X-MS-CLIENT-PRINCIPAL-NAME, зависит от параметров, которые вы настроили на портале Azure для раздела параметров проверки подлинности учетной записи Microsoft вашего веб-приложения.
Если вы установите для параметров аутентификации учетной записи Microsoft значение wl.basic , тогда значением X-MS-CLIENT-PRINCIPAL-NAME будет удобочитаемое имя (например, «День Бенджамина»). Если для параметров аутентификации учетной записи Microsoft установлено значение wl.basic плюс wl.emails , то значением X-MS-CLIENT-PRINCIPAL-NAME будет идентификатор пользователя учетной записи MSA для текущего пользователя (например, «[email protected]»). ).
Если ваше приложение настроено только для запроса wl.basic от пользователя, вы не сможете увидеть его / ее адрес электронной почты.
Убедитесь, что ваше приложение настроено для wl.basic и wl.emails
- Откройте новую вкладку в вашем браузере и перейдите к https://portal.azure.com
- В разделе Службы приложений перейдите на страницу конфигурации своего веб-приложения Azure {{Имя приложения}} .
- Нажмите на Аутентификацию / Авторизацию
- Под Аутентификацией / Авторизацией , нажмите на Microsoft
- Убедитесь, что базовая и wl.emails проверены.
- В нижней части лезвия нажмите кнопку ОК .
- Если вы внесли изменения в предыдущий блейд, нажмите « Сохранить» (ПРИМЕЧАНИЕ: если вы не внесли никаких изменений, эта кнопка будет недоступна.)
- В браузере вернитесь на вкладку « Сводка безопасности ».
Страница «Сводка безопасности», часть 2: конечная точка службы /.auth/me
Вы должны вернуться на страницу « Сводка безопасности» . Azure Easy Auth имеет конечную точку службы с адресом /.auth/me . Служба /.auth/me позволяет получить доступ к строке JSON со всей информацией, которую служба проверки подлинности приложения Azure знает о текущем пользователе.
- Прокрутите вверх до верхней части страницы.
- В верхней части страницы нажмите на ссылку Auth Me Info .
- Теперь вы должны быть на новой вкладке, и вы должны увидеть кучу данных JSON. Если вы получили пустую строку JSON или получили сообщение об отказе в доступе, вернитесь к Сводке по безопасности, нажмите и нажмите «Войти». После того, как вы вошли в систему, снова нажмите на ссылку Auth Me Info.
Этот большой блок JSON - это то, что Azure Easy Auth знает о вас. Особенно важная вещь в JArray называется user_claims . Поскольку Azure Easy Auth работает с использованием удостоверений на основе утверждений, все эти фрагменты информации представляются в виде отдельных пар имя-значение. Каждая из этих пар имя-значение называется заявкой .
[
{
«Access_token»: «токен отредактирован по соображениям безопасности»,
«Expires_on»: «2018-05-21T20: 06: 47.754206Z»,
«Provider_name»: «microsoftaccount»,
«User_claims»: [
{
«Typ»: «http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier»,
«Val»: «66759c6053a12290»
}, {
«Typ»: «http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress»,
«Val»: «[email protected]»
}, {
«Typ»: «http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name»,
«Валь»: «День Вениамина»
} , {
«Typ»: «http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname»,
«Валь»: «Вениамин»
}, {
«Typ»: «http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname»,
«Val»: «день»
} ,
...
],
«User_id»: «[email protected]»
}
]
Если вы посмотрите на Сводку безопасности , то заметите, что раздел Сводка претензий пуст.
Давайте это исправим.
Заполнение утверждений пользователей с помощью специального промежуточного программного обеспечения ASP.NET
Хорошо. Итак, давайте быстро подведем итоги, где мы находимся. В нашем приложении есть страница « Сводка по безопасности», которая может отображать наши утверждения и заголовки HTTP для каждого запроса. Мы знаем, что в заголовках есть информация о пользователе, если этот пользователь вошел в систему Easy Auth. Мы также знаем, что если пользователь вошел в систему, то он / она может получить доступ к конечной точке службы /.auth/me, чтобы получить отформатированную в JSON информацию об аутентифицированном пользователе.
Этот / .auth/me JSON содержит некоторые полезные данные, которые было бы очень приятно вывести на экран и использовать в нашем приложении. В частности, есть претензии на имя (имя), фамилию (фамилию), идентификатор пользователя и адрес электронной почты.
Так почему же наши требования пусты, когда мы переходим к Сводке безопасности? Честно говоря, я не уверен. Если бы вы работали с приложением, использующим Easy Auth и ASP.NET Classic (иначе не «Core»), эти заявки были бы автоматически заполнены для вас. Я предполагаю, что поскольку ASP.NET Core все еще довольно нов, то Easy Auth еще не полностью на 100% поддерживает ASP.NET Core.
Сейчас нам нужно перехватить входящий HTTP-запрос и заполнить заявки. Для этого мы будем использовать часть промежуточного программного обеспечения. Промежуточное программное обеспечение - это кусок кода, который, ммм, находится в середине конвейера HTTP-запросов. Это посередине, поэтому промежуточное ПО. В любом случае, промежуточное ПО имеет доступ к контексту выполнения запроса и позволяет нам выполнять пользовательские действия. Существует несколько способов написания промежуточного программного обеспечения, но самый простой и безопасный для типов способ - создать класс, реализующий интерфейс Microsoft.AspNetCore.Http.IMiddleware .
В примере приложения в пространстве имен Security существует класс с именем PopulateClaimsMiddleware, который при вызове заполняет заявки для текущего пользователя, используя значения заголовка и данные из службы /.auth/me.
общедоступный класс PopulateClaimsMiddleware: IMiddleware {публичная асинхронная задача InvokeAsync (контекст HttpContext, RequestDelegate next) {List <Claim> Applicans = новый список <Claim> (); AddClaimsFromHeader (контекст, утверждения); AddClaimsFromAuthMeService (контекст, утверждения); var identity = новый ClaimsIdentity (претензии); context.User = new System.Security.Claims.ClaimsPrincipal (identity); ждать следующего (контекст); } ...}
В коде промежуточного программного обеспечения некоторые значения берутся из заголовков, а некоторые значения берутся из службы /.auth/me. В конечном итоге все значения устанавливаются в свойстве User текущего объекта HttpContext, чтобы оно было доступно на протяжении оставшейся части выполнения запроса.
Код в AddClaimsFromAuthMeService () использует класс AzureEasyAuthClient для вызова службы в /.auth/me с использованием авторизованного токена безопасности пользователя. Действительно важный код в AzureEasyAuthClient - это код, который захватывает файл cookie AppServiceAuthSession из HTTP-запроса пользователя и присоединяет этот же файл cookie к вызову службы в /.auth/me. Передача этого cookie-файла - это то, как этот код HttpClient аутентифицируется с помощью службы /.auth/me.
ПРИМЕЧАНИЕ: теоретически вы можете передать токен, который находится внутри этого файла cookie AppServiceAuthSession, в службу /.auth/me, используя заголовок с именем «x-zumo-auth». К сожалению, я не смог заставить это работать, и документация для аутентификации приложений Azure (также известная как Easy Auth) практически отсутствует.
private void TryInitializeHttpClientUsingSessionCookie (запрос HttpRequest) {var requestCookies = request.Cookies; if (requestCookies.ContainsKey (SecurityConstants.Cookie_AppServiceAuthSession) == false) {IsReadyForAuthenticatedCall = false; } else {var handler = new HttpClientHandler (); var client = новый HttpClient (обработчик); var baseUrl = $ "{request.Scheme}: // {request.Host}"; client.BaseAddress = new Uri (baseUrl); var container = new CookieContainer (); handler.CookieContainer = container; var authCookie = requestCookies [SecurityConstants.Cookie_AppServiceAuthSession]; container.Add (новый Uri (baseUrl), новый Cookie (SecurityConstants.Cookie_AppServiceAuthSession, authCookie)); IsReadyForAuthenticatedCall = true; _Client = клиент; }}
Также в пространстве имен Security есть класс ExtensionMethods.cs . В этом классе есть метод UsePopulateClaimsMiddleware () . Этот метод имеет логику для подключения промежуточного программного обеспечения к конвейеру выполнения ASP.NET Core.
открытый статический класс ExtensionMethods {открытый статический IApplicationBuilder UsePopulateClaimsMiddleware (этот построитель IApplicationBuilder) {return builder.UseMiddleware <PopulateClaimsMiddleware> (); } ...}
Включение нашего промежуточного программного обеспечения в ASP.NET Core
Давайте подключим промежуточное программное обеспечение в приложение.
- В Visual Studio перейдите в Обозреватель решений . В веб-проекте найдите Startup.cs и откройте его.
- В редакторе для автозагрузки. cs , найдите метод Configure () .
- Раскомментируйте строку с надписью app.UsePopulateClaimsMiddleware ();
- В редакторе для Startup.cs найдите метод ConfigureServices (). Добавьте следующую строку в ConfigureServices (), как показано ниже:
services.AddTransient <PopulateClaimsMiddleware> ();
- Скомпилируйте решение.
- Разверните веб-приложение в своем веб-приложении Azure, щелкнув правой кнопкой мыши -> Развернуть .
- В браузере перейдите к Сводка безопасности .
- Убедитесь, что сводка утверждений теперь заполнена утверждениями. ПРИМЕЧАНИЕ. Если сводка утверждений по-прежнему пуста, нажмите кнопку «Вход» в верхней части сводки безопасности и снова войдите в систему.
Хорошо. Мы подключили промежуточное программное обеспечение и заполняем требования пользователей.
Но мы не делаем с ними ничего полезного. Давайте воспользуемся утверждениями для заполнения раздела « Сведения о пользователе » в «Сводке безопасности».
Измените SecuritySummaryController для доступа к IUserInformation
Если мы хотим получить доступ к утверждениям пользователя, они доступны нам, обратившись к свойству User в HttpContext или через свойство User в базовом классе ASP.NET Controller. Теперь мы можем получить доступ к утверждениям напрямую, но если мы хотим сохранить наш код в чистоте, часто неплохо создать отдельный класс, который знает, как получить доступ к этим утверждениям. В примере приложения уже есть интерфейс с именем IUserInformation и класс с именем UserInformation . Давайте подключим это к коду SecuritySummaryController.
- В Visual Studio откройте SecuritySummaryController.cs
- Вверху класса SecuritySummaryController добавьте следующий оператор using: usingEasyAuthDemo.WebUi.Security;
- В самом классе добавьте следующий код курсивом .
открытый класс SecuritySummaryController: Controller { private IUserInformation _UserInfo; public SecuritySummaryController (IUserInformation userInfo) { if (userInfo == null) { выбросить новое ArgumentNullException (nameof (userInfo), $ "{nameof (userInfo)} равно нулю."); } _UserInfo = userInfo; } ...}
- Найдите метод PopulateUserInfo ()
- Измените код в методе PopulateUserInfo () на следующий код:
private void PopulateUserInfo (модель SecuritySummaryViewModel) {model.IsLoggedIn = _UserInfo.IsLoggedIn.ToString (); model.FirstName = _UserInfo.FirstName; model.LastName = _UserInfo.LastName; model.EmailAddress = _UserInfo.EmailAddress; }
- Откройте Startup.cs
- Найдите ConfigureServices ()
- Добавьте следующий код в ConfigureServices ()
public void ConfigureServices (IServiceCollection services) {services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor> (); services.AddTransient <PopulateClaimsMiddleware> (); services.AddTransient <IUserInformation, UserInformation> (); services.AddMvc (); ConfigureAuthentication (услуги); ConfigureAuthorization (услуги); }
- В пространстве имен Security найдите и откройте UserInformation.cs
Класс UserInformation имеет всю логику для доступа к утверждениям текущего пользователя и получения значений для требуемых утверждений. Он также получил логику, чтобы убедиться, что он безопасно обрабатывает, когда пользователь не вошел в систему и / или желаемая претензия не существует в коллекции претензий пользователя. Использование этой логики в своем собственном классе делает код намного менее подверженным ошибкам и сохраняет логику чтения утверждений очень чистой и организованной.
Вот совет. Доступ к претензиям может стать кошмаром кодирования. Сделайте себе одолжение и держите ваш код организованным. Что еще более важно, следите за дублированием кода!
- Скомпилируйте решение
- Разверните обновленную версию приложения в Azure, щелкнув правой кнопкой мыши -> Развернуть .
Убедитесь, что информация пользователя заполняется из утверждений
Обновленная версия приложения должна быть развернута в Azure. Давайте проверим, что мы читаем информацию о претензиях и размещаем ее на экране.
- В браузере перейдите на {{URL-адрес службы приложений}}, чтобы просмотреть свое приложение
- Перейти к сводке безопасности
- Убедитесь, что вы вошли в систему
- Найдите раздел Информация о пользователе
- Убедитесь, что информация о пользователе заполняется вашей информацией.
Если раздел с информацией о пользователе заполнен, все готово!
Резюме
Вот краткое изложение того, что мы сделали.
Мы хотели использовать проверку подлинности приложений Azure (упрощенную проверку подлинности) с ASP.NET Core и проверку подлинности на основе утверждений. Для этого мы добавили часть специального промежуточного программного обеспечения, которое подключилось к конвейеру запросов ASP.NET Core и заполнило аутентифицированного пользователя в HttpContext. Как только мы это сделали, мы использовали служебный объект для доступа к заявкам пользователя и отображения их на странице в Сводке безопасности.
Поздравляем! У вас есть проверка подлинности на основе утверждений, работающая с веб-приложением Azure и ASP.NET Core.