Аутентификация и авторизация в приложениях на платформе Windows Azure.

Давайте подумаем над следующим вопросом: меняются ли подходы к аутентификации и авторизация для приложений, использующих Windows Azure, или, иными словами, поговорить об управление доступом и проверкой подлинности для Windows Azure приложений.

На самом деле однозначного ответа нет: с одной стороны есть возможность перенести приложение абсолютно без изменения механизмов аутентификации и авторизации (например, ASP.NET аутентификация на основе форм и ASP.NET Membership Provider), а с другой стороны - наиболее эффективным и рекомендованный способом является использование утверждений (claim).

Предлагаю сейчас обзорно поговорить об аутентификации на основе утверждений и ориентироваться на следующие два сценария:

  1. Миграция в Windows Azure интранет веб-приложения, которое использует привычный способ аутентификации, например, Active Directory, т.е. доступ разрешен только внутрикорпоративным пользователям (Windows Integrated аутентификация).Веб-приложения, которое должно интегрироваться с LiveID, Google, Facebook или OpenID провайдерами.

Каким образом наше приложение должно управлять доступом и проверкой подлинности для этих случаев? Ответом может являться управление доступом на основе заявок (Claims Based Identity).

Что такое управление доступом на основе заявок (Claims Based Identity)?

В традиционных приложениях можно выделить два наиболее применимых механизма управления доступом и проверки подлинности:

  1. Использование нижележащей инфраструктуры или встроенных, например, в операционную систему способов аутентификации (Active Directory, Access Control List и т.п.), т.е. специально слоя проверки в приложении не присутствует. У данного способа есть существенный минус – он работает только в пределах вашей внутренней сети и в рамках изолированного от внешнего мира приложения.
  2. Использование собственного слоя идентификации и проверки: локальное хранение учетных данных, собственная логика поверки и иногда даже шифрование. Примером может служить хорошо знакомый 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).

Допустим, что доверительные отношения установлены, тогда сам процесс можно описать следующим образом:

  1. Пользователь обращается к приложению, приложение сообщает: какой маркер требуется, что именно должно содержать утверждение и какому провайдеру удостоверений (IP-STS) оно доверяет (в данном случае Вашему локальному AD, т.к. были установлены отношения доверия). Сообщить эти данные приложение может двумя способами: с использование WS-SecurityPolicy (если клиент обратился через SOAP, например, к веб-сервису) и HTML-ответ (если клиент обратился напрямую через веб-браузер).
  2. Далее пользователь обращается (происходит автоматическая переадресация в браузере) к соответствующему провайдеру удостоверений (IP-STS), который аутентификацию. При этом способ аутентификации может быть любым, вернее, тем, который поддерживает данный провайдер удостоверений (например, для данного случая – это может быть Керберос).
  3. После успешной аутентификации IP-STS выдает клиенту специальный маркер (security token), содержащий одно или несколько утверждений. Полученный маркер подписывается сертификатом (в процессе установления доверительных отношений между ADFS и приложением как раз происходил обмен сертификатами).
  4. Данный маркер отправляется приложению.
  5. 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 может быть несколько абсолютно равноправным экземпляров приложения? Верно, здесь следует обратить внимание на следующие моменты:

  1. Windows Azure приложение может иметь различные URI в зависимости от среды: локальный эмулятор, предпромышелнная (staging), промышленная (production). А для WIF определяет адрес возврата (в файле конфигурации), на который маркер безопасности возвращается. Это означает, что необходимо следить за тем, чтобы URI был корректным.
  2. Второго особенность при работе с сертификатами (т.к. subject поле сертификата может отличаться от URI в локальной среде эмулятора Windows Azure).
  3. И еще одна особенность – это метод шифрования, которые применяются для куки. По умолчанию сессионные куки 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:

  1. Вызовы SOAP веб-сервисов, развернутых в Windows Azure. Работает аналогично. Здесь стоит только обратить внимание на то, что не требуется переадресация (см. Active, Passive and Passive-Aggressive, eng).
  2. Вызовы REST-сервисов. На данный момент в WIF нет прямой поддержки REST-сервисов, но это возможно достаточно реализовать с помощью расширения WIF для поддержки OAuth (см. Protecting and consuming REST based resources with ACS, WIF, and the OAuth 2.0 protocol, eng).
  3. Мобильные приложения (см. пример для Windows Phone Access Control Service Samples and Documentation), в которых Вы можете с помощью ACS и WIF реализовать описанные выше методы аутентификации (LiveID, Google, Facebook, AD) и обращение к REST-сервисам через OAuth.