Аутентификация и авторизация в приложениях на платформе Windows Azure
Давайте подумаем над следующим вопросом: меняются ли подходы к аутентификации и авторизация для приложений, использующих Windows Azure, или, иными словами, поговорить об управление доступом и проверкой подлинности для Windows Azure приложений.
На самом деле однозначного ответа нет: с одной стороны есть возможность перенести приложение абсолютно без изменения механизмов аутентификации и авторизации (например, ASP.NET аутентификация на основе форм и ASP.NET Membership Provider), а с другой стороны - наиболее эффективным и рекомендованный способом является использование утверждений (claim).
Предлагаю сейчас обзорно поговорить об аутентификации на основе утверждений и ориентироваться на следующие два сценария:
- Миграция в Windows Azure интранет веб-приложения, которое использует привычный способ аутентификации, например, Active Directory, т.е. доступ разрешен только внутрикорпоративным пользователям (Windows Integrated аутентификация).
- Веб-приложения, которое должно интегрироваться с LiveID, Google, Facebook или OpenID провайдерами.
Каким образом наше приложение должно управлять доступом и проверкой подлинности для этих случаев? Ответом может являться управление доступом на основе заявок (Claims Based Identity).
Что такое управление доступом на основе заявок (Claims Based Identity)?
В традиционных приложениях можно выделить два наиболее применимых механизма управления доступом и проверки подлинности:
- Использование нижележащей инфраструктуры или встроенных, например, в операционную систему способов аутентификации (Active Directory, Access Control List и т.п.), т.е. специально слоя проверки в приложении не присутствует. У данного способа есть существенный минус – он работает только в пределах вашей внутренней сети и в рамках изолированного от внешнего мира приложения.
- Использование собственного слоя идентификации и проверки: локальное хранение учетных данных, собственная логика поверки и иногда даже шифрование. Примером может служить хорошо знакомый ASP.NET Membership Provider, который требует для каждого приложения вести уникальную базу пользователей и т.п.
Что же с подобными приложениями происходит в Облаке? Если мы переносим приложение первого типа в PaaS инфраструктуру, то для его корректной работы потребуется внести небольшие изменения (какие именно рассказано далее). Для приложения второго типа в PaaS может потребоваться дублирование и синхронизация учетных данных.
Управление доступом на основе заявок как раз является подходом, находящимся где-то посередине и решающим многие проблемы. Фактически создается дополнительный слой\сервис, который скрывает от нас внутреннюю логику и предоставляет единый (стандартный) фасад\интерфейс. Данный интерфейс описывается контрактом и основывается на отрытых протоколах, которые реализуют практически все вендоры (Microsoft, Oracle, Sun, IBM и т.п.). Этот фасад – это не что иное, как специальная служба (Security Token Service, STS).
Есть две разновидности службы STS: служба поставщика удостоверений (IP-STS) и служба проверяющей сторона (RP-STS). Нас интересует IP-STS, которая проверяет подлинность клиента, используя, например, встроенную проверку подлинности Windows. Она создает маркер (например, SAML) на основе утверждений (claim), представленных клиентом, и может добавить свои собственные утверждения. Приложение проверяющей стороны получает маркер (например, SAML) и, проанализировав содержащиеся в нем утверждения, решает, следует ли предоставить клиенту доступ к запрошенному ресурсу. Подобный абстрактный слой и унификация позволяют использовать логику идентификации за пределами, например, внутренней инфраструктуры.
Каким образом данная схема работает для интранет веб-приложения, перемещенного в Windows Azure?
Реализация данного сценария достигается за счет использования Active Directory Federation Services 2.0 (ADFS 2.0).
AD FS 2.0 - это роль Windows Server, реализующая возможности аутентификации на основе заявок. AD FS 2.0 расширяет AD службой Security Token Service, который предоставляет возможность пользователям аутентифицироваться в приложении вне зависимости от того, где оно развернуто. AD FS 2.0 основывает на следующих открытых стандартах WS-Trust, WS-Federation и протоколе SAML 1.0\2.0.
Если мы говорим о Windows Azure, то для реализации подобной схемы необходимо использовать в приложение Windows Identity Foundation (WIF) или подобный стек, который поддерживает необходимые открытые стандарты безопасности. И тогда AD FS 2.0 позволит пользователю с учетной записью в локальной AD получить доступ к приложению в Windows Azure. При этом нет необходимости в создании новых или дублировании существующих учетных записей, синхронизации паролей и т.п. – для Вашего приложения все абсолютно прозрачно. С инфраструктурной точки зрения потребуется установить доверительные отношения между локальным AD FS 2.0 и Windows Azure приложением и обменяться сертификатами (более детально процесс описан в документе Single Sign-On from Active Directory to a Windows Azure Application, eng).
Допустим, что доверительные отношения установлены, тогда сам процесс можно описать следующим образом:
- Пользователь обращается к приложению, приложение сообщает: какой маркер требуется, что именно должно содержать утверждение и какому провайдеру удостоверений (IP-STS) оно доверяет (в данном случае Вашему локальному AD, т.к. были установлены отношения доверия). Сообщить эти данные приложение может двумя способами: с использование WS-SecurityPolicy (если клиент обратился через SOAP, например, к веб-сервису) и HTML-ответ (если клиент обратился напрямую через веб-браузер).
- Далее пользователь обращается (происходит автоматическая переадресация в браузере) к соответствующему провайдеру удостоверений (IP-STS), который аутентификацию. При этом способ аутентификации может быть любым, вернее, тем, который поддерживает данный провайдер удостоверений (например, для данного случая – это может быть Керберос).
- После успешной аутентификации IP-STS выдает клиенту специальный маркер (security token), содержащий одно или несколько утверждений. Полученный маркер подписывается сертификатом (в процессе установления доверительных отношений между ADFS и приложением как раз происходил обмен сертификатами).
- Данный маркер отправляется приложению.
- Windows Azure приложение проверят данный маркер и его подпись (валидирует), т.е. удостоверяется, что маркер выданным STS, которому приложение доверяет. Если все верно, то приложение извлекает утверждения, содержащиеся в маркере, и выполняет аутентификацию и авторизацию пользователя.
WIF в данном случае отвечает за всю логику: обращение к провайдеру удостоверений, валидация маркера, извлечение утверждений и т.п. Это позволяет отделить бизнес-логику приложения от модуля идентификации.
Давайте немного подробнее рассмотрим взаимодействие WIF и ASP.NET.
WIF включает 3 модуля, которые являются часть процесса обработки HTTP запросов в ASP:
- модуль федеративной аутентификации (Federated Authentication Module, FAM);
- модуль сессией (Session Authentication Module, SAM);
- модуль авторизации (Claims Authorization Module, CAM).
FAM отвечает за работу с маркерами (security ticket). FAM перехватывает первое обращение к приложению (т.е. еще не аутентифицированный запрос) и переадресовывает его к провайдеру удостоверений (IP-STS). После получение маркера от IP-STS FAM его валидирует.
SAM отвечает за работу с сессиями, например, создает сессионный куки и отправляет его обратно пользователю, т.е. последующие обращения клиента к порталу не потребуют проходить этот сложный процесс (получение маркера) повторно. Здесь же Вы можете внедрить свою собственную логику.
CAM выполняет авторизацию. WIF полностью интегрирован с ролевой-моделью ASP.NET, например, метод IsInRole корректно функционирует.
Теперь зная данный механизм, обратим внимание на пункт 4 процесса аутентификации – возврат маркера приложение. Стоп?! А как же маркер отправляется приложению, если в Windows Azure может быть несколько абсолютно равноправным экземпляров приложения? Верно, здесь следует обратить внимание на следующие моменты:
- Windows Azure приложение может иметь различные URI в зависимости от среды: локальный эмулятор, предпромышелнная (staging), промышленная (production). А для WIF определяет адрес возврата (в файле конфигурации), на который маркер безопасности возвращается. Это означает, что необходимо следить за тем, чтобы URI был корректным.
- Второго особенность при работе с сертификатами (т.к. subject поле сертификата может отличаться от URI в локальной среде эмулятора Windows Azure).
- И еще одна особенность – это метод шифрования, которые применяются для куки. По умолчанию сессионные куки WIF шифрует с помощью DPAPI, это означает, что данный куки может быть расшифрован только тем же экземпляром веб-роли. Поэтому необходимо использовать альтернативный механизм, например, RsaEncryptionCookieTransform, который шифрует куки с помощью того же сертификата, что и используемого для SSL.
Более подробно сам процесс и настройка для пунктов 1-3 приведена в документе Использование федеративной аутентификации в веб-приложении под Windows Azure (rus).
Идентификация через LiveID, Google, Facebook.
Здесь нам поможет Access Control Services (ACS). ACS – это провайдер федерации (federation provider, FP). FP аналогичен IP в STS, за исключением того, что он не аутентифицирует пользователя, а преобразовывает маркер из одного формата в другой. Приложение может быть настроено так, что оно принимает маркеры только от FP, а FP в свою очередь на вход принимает различные маркеры и преобразует их в единый формат, понятный приложению. Фактически это схема нормализации учетных данных.
ACS содержит STS, позволяет настроить отношения доверия с различными системами проверки подлинности, задать правила преобразования\нормализации маркеров и т.п. Так же ACS предоставляет, например, страницу выбора провайдера аутентификации или даже более того, умеет на основании email адреса определять домен и автоматически перенаправлять на страницу аутентификации соответствующего провайдера учетных данных.
Итак, каким образом мы можем разрешить аутентификацию на нашем портале для пользователей LiveID, Google, Facebook и т.п.?
Перечисленные провайдеры используют различные протоколы аутентификации. Одна из возможностей расширить WIF для непосредственной поддержки этих провайдеров, но это достаточно трудоемко и требует постоянной поддержки и обновления.
Вот здесь нам и поможет ACS (провайдер федерации), который позаботиться о преобразовании различных протоколов к единому представлению (protocol transition). При этом приложение при необходимости может определить оригинальный источник выданного удостоверения. При этом никаких дополнительный требований по реализации на приложение это не накладывает.
Здесь я хочу заметить, что обычного при подобной схеме аутентификации приложение так же хранит локально дополнительную информацию о пользователях – локальный профиль, который связан с LiveID, Google, Facebook идентификатором. Это связано с тем, что маркер от провайдера не всегда содержит данные, которые нам необходимы, например, предпочтения, список покупок и т.п.
Подобный сценарий идентификации на основе публичных провайдеров очень хорошо работает для выявления уникальный пользователей, упрощения схемы регистрации на сайте, когда посетителям не требуется заводить отдельную учетную запись на вашем портале и т.п. (забывать\запоминать\восстанавливать пароль и т.п.).
Выводы
На самом деле сценариев, конечно, больше и все они так же могут быть реализованы с помощью WIF и ACS:
- Вызовы SOAP веб-сервисов, развернутых в Windows Azure. Работает аналогично. Здесь стоит только обратить внимание на то, что не требуется переадресация (см. Active, Passive and Passive-Aggressive, eng).
- Вызовы REST-сервисов. На данный момент в WIF нет прямой поддержки REST-сервисов, но это возможно достаточно реализовать с помощью расширения WIF для поддержки OAuth (см. Protecting and consuming REST based resources with ACS, WIF, and the OAuth 2.0 protocol, eng).
- Мобильные приложения (см. пример для Windows Phone Access Control Service Samples and Documentation), в которых Вы можете с помощью ACS и WIF реализовать описанные выше методы аутентификации (LiveID, Google, Facebook, AD) и обращение к REST-сервисам через OAuth.