Что такое Native App?
Native Apps, или public clients, или публичные клиенты — это приложения, которые вызывают Web API от имени пользователя. Типичный пример таких клиентов — это мобильные приложения iOS и Android. Эти приложения получают access token от имени пользователя по протоколу OAuth 2.0. Этот access token (маркер доступа) затем посылается в HTTP запросе к Web API, который и авторизует пользователя и затем возвращает желаемый ресурс.
Отличие от Web Apps заключается в том, что в качестве клиента в Web app используется браузер, который аутентифицирует клиент в web приложении. Web приложение перенаправляет браузер пользователя на точку аутентификации Azure AD, а AAD в ответ возвращает запрос на аутентификацию.
Интеграция с Azure AD
Для того, чтобы иметь возможность выполнять аутентификацию в приложении с помощью Azure AD, для начала необходимо выполнить регистрацию приложения в AAD тенанте. При регистрации приложения указывается:
- Redirect URI — это место, куда AAD пошлет ответ аутентификации, включая токен, в случае успешной аутентификации.
- Application ID URI — идентификатор приложения. Это значение посылает приложение, чтобы показать, для какого приложения нужен токен. Потом это же значение указывается к токене в виде target (для кого токен предназначен).
После регистрации в ответ мы получаем Application ID (AppID). Затем, в коде приложения мы должны указать как AppID, так и AppID URI и Redirect URI, точно такие как в в AAD.
Тонкость заключается в том, что мобильное приложение обращается к дефолтному браузеру на мобильном устройстве для аутентификации в фоновом режиме (Safari для iOS, Chrome для Android). Дальше, в зависимости от выбранного варианта аутентификации, используя браузерный pop-up или брокерную аутентификацию, мобильное приложение обращается к authorization endpoint в Azure AD, сообщая AppID и redirect URI.
Здесь есть несколько возможных вариантов или сценариев аутентификации (authentication flows). Microsoft еще их называет потоками проверки подлинности.
Также, хочу напомнить, что Microsoft проставляет две версии платформы Azure AD Identity Platform, которые различаются и потоками аутентификации, и маркерами и точками входа (endpoints). Актуальная платформа — v2. Версию 1 использовать не стоит, так как компания в ее разработку и поддержку больше не вкладывается, а в дальнейшем, скорее всего и уберет её поддержку.
Версия платформы v1 поддерживает библиотеки аутентификации ADAL, в то время как v2 — более актуальную MSAL.Поэтому здесь мы будем говорить только о работе с платформой v2.
Authentication flows
Итак, для мобильных приложений существуют следующие сценарии аутентификации:
Интерактивный | Получает маркер через интерактивный процесс, который запрашивает у пользователя учетные данные через браузер или всплывающее окно. |
Код авторизации | Используется в приложениях, установленных на устройстве для получения доступа к защищенным ресурсам, таким как web-API.Это позволит вам добавить доступ к мобильным и классическимприложениям с помощью функции входа и доступа через API. |
Код устройства | Позволяет пользователям входить на устройства с ограниченным входом, например на интеллектуальный телевизор, на устройство IoT или на принтер. |
Первый и самый очевидный режим — интерактивный, — который поддерживается на платформе разработки Xamarin для iOS и Android. Microsoft предоставляет MSAL.NET библиотеку (MSAL.objc для iOS и MSAL.Android), которую надо интегрировать в ваш проект на Xamarin, для аутентификации.
Но наиболее ярким и часто встречающимся примером является режима Authorization code flow (кода авторизации) на базе протокола OAuth 2.0. Чаще всего такой сценарий используется, чтобы из приложения, установленного на устройстве, получать доступ с защищенный web API.
Когда пользователь логинится в веб приложение, оно получает код авторизации (authorization code). Этот код авторизации активируется для получения маркера для вызова web API (access token). В ASP.NET и ASP.NET Core веб-приложениях единственной целью AcquireTokenByAuthorizationCode
является добавление маркера в кэш маркеров (token cache). Что важно, когда авторизации ваше приложение отлучает от имени пользователи и с правами пользователя, который логинится. Затем маркер может использоваться приложением и обновляться (refresh access token) прозрачно в тихом режим (AcquireTokenSilent
).
Запрос кода авторизации выглядит следующим образом:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fuser.read&state=12345
Мы видим, что обращение происходит к endpoint /authorize, client_id — это AppID вашего зарегистрированного приложения в Azure AD, response_type — всегда code для этого типа авторизации, response_mode — передает код как сроку HTTP запроса с параметрами о относительно redirect URI.
redirect_uri — непосредственно ресурс (URL), в котором мы хотим авторизоваться, куда и будет передан токен. Он должен в точности совпадать с тем, что в свойствах вашего зарегистрированного в AAD приложения.
Для мобильных приложений оно может быть дефлотным:
https://login.microsoftonline.com/common/oauth2/nativeclient
scope — это типы прав доступа, которые выдается к тому или иному ресурсу. Чаще всего в случае в Azure AD объектами и правами к облачным сервисам Azure и Office 365 (Exchange Online, Sharepoint Onlin), следует использовать открытый API: Microsoft Graph: https://graph.microsoft.com.
C помощью этого API и протокола авторизации OAuth 2.0 вы можете получить доступ, например, к календарю пользователя (Calendars.Read
) или послать письмо от имени пользователя (Mail.Send). Для этого в свойствах зарегистрированного приложения надо указать скоупы прав, которые есть у приложения, и которые он может использовать при обращении к Graph API от имени пользователя. В примере выше это был — User.Read.
Полный список прав в Graph API доступен по ссылке:
https://docs.microsoft.com/ru-ru/graph/permissions-reference
Полученный код авторизации будет выглядеть следующим образом:
GET https://login.microsoftonline.com/common/oauth2/nativeclient?code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq…
&state=12345
Далее запрос access token будет выглядеть следующим образом:
https://login.microsoftonline.com/common/oauth2/v2.0/token?client_id=6731de76-14a6-49ae-97bc-6eba6914391e &scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read &code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr... &redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F &grant_type=authorization_code
В примере выше code — это и и есть код авторизации.
Поскольку формат токена OAuth 2.0 — JSON (JavaScript Object Notation), то сам токен доступа будет выглядет так:
{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q…",<br> "token_type": "Bearer",<br> "expires_in": 3599,<br> "scope": "https%3A%2F%2Fgraph.microsoft.com%2Fuser.read",<br> "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4…",<br> "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD…",<br> }
Затем, можно обращаться к приложению или ресурсам, вставив полученный токен в HTTP Authorization заголовок (header).
MSAL автоматически обновляет токены (стандартный таймаут — 90 дней).
Конечно, если вы используете Graph API только для аутентификации в Azure AD, то дефолтных прав User.Read вам будет достаточно. Эти права нужны, чтобы прочитать пользователя из Active Directory.
Настройка мобильного приложения
Ранее, в v1 при регистрации приложения в AAD, необходимо, чтобы разработчик приложения предоставил Redirect URI из своего кода. Сейчас, в v2 ситуация упростилась.
Azure AD поддерживает проекты, созданные в языках: Xamarin (для iOS и Android), Swift и Objective-C для iOS и Java, Kotlin для Android. Kotlin набирает все большую популярность.
Вот пример использования MSAL на Java: com.microsoft.identity.client. А готовый пример проекта для Android можно скачать здесь.
Затем, полученный Package name (Android ) или Bundle ID (iOS) необходимо добавить в свойства зарегистрированного в AAD приложения. В случае Android, придется также еще добавить Signature hash — по этому хэшу Microsoft проверяет целостность пакета при логине. Чтобы получить hash, необходимо использовать утилиту Keytool с ключами вашего приложения:
keytool -exportcert -alias SIGNATURE_ALIAS -keystore PATH_TO_KEYSTORE | openssl sha1 -binary | openssl base64<br>
Большей деталей, о том как подписать ваше Android приложение, читайте здесь.
Вставив эти данные в Azure portal, вы получаете Redirect URI и MSAL код, который необходимо вставить в код приложения:
{ "client_id" : "e004c29a-15e1-4c16-8833-xxxxxxxxxxxx", "authorization_user_agent" : "DEFAULT", "redirect_uri" : "msauth://your.package.name/qXaJUYqFXJSwVg6Opy7ryHxN0Oo%3D", "authorities" : [ { "type": "AAD", "audience": { "type": "AzureADMyOrg", "tenant_id": "705d07a3-2eea-4f3b-ab59-xxxxxxxxxxxx" } } ] }
Затем, вам остается настроить ваше приложение, добавив в него json файл с регистрационной информацией и импортировав нужные библиотеки.
В библиотеке MSAL для Android используются методы acquireTokenSilentAsync()
и acquireToken()
для получения токена. Первый получает токен без взаимодействия с пользователем, если информация о его аккаунте присутствует. acquireToken()
удобно использовать тогда, когда пользователю необходимо пройти двухфакторную аутентификацию (MFA). Также, второй метод, может использовать куки файлы из дефолтного браузера и может брать информацию об аккаунте из приложения MS Authenticator, если используется брокерная аутентификация. так вы обеспечите SSO для пользователя.
D MSAL для iOS используется класс ViewController
и его методы initMSAL
для инициализации и acquireTokenSilently()
иacquireTokenInteractively()
для получения токенов. Дейсвтуют аналогично перечисленным выше для Android.
Соотвественно, вам надо добавить информацию о регистрации в AAD в ViewController.swift (AppID, Graph URI, scopes, endpoint URI), и несколько функций, использующих перечисленые выше методы в класс ViewController
.
Более детально, читайте гайд с примерами кода для iOS и Android.
Брокерная аутентификация
Если вы хотите обеспечить функционал и удобство single sign-on (SSO), требуется использовать брокерную аутентификацию. Брокером будет выступать приложение MS Authenticator, которые хранит информацию об аккаунтах пользователя в Azure AD. Особенно это удобно, если мобильное устройство управляется через Intune — в этом случае аккаунт пользователя уже будет в приложении. Когда это приложение установлено, методы
acquireToken() библиотеки MSAL обрабатываются брокером, а не библиотекой локально.
Это же мобильное приложение поддерживает токен в актуальном состоянии и обновляет его до тех пор, пока пользователь не поменял пароль от аккаунта. После этого ему придется залогиниться снова.
Брокер требует redirect URI, который с ним совместим. Формат должен быть:
msauth://<yourpackagename>/<base64urlencodedsignature>
Чтобы сгенерировать Base64 кодированный URL, используйте ключи для подписи приложения и команду keytool:
keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%.android\debug.keystore | openssl sha1 -binary | openssl base64
После этого в json файле конфигурации MSAL необходимо указать redirect uri вашего брокера.
Брокерная аутентификация для iOS поддерживается в Xamarin. Для этого разработчики приложения должны использовать параметр
WithBroker(), когда они вызывают метод
PublicClientApplicationBuilder.CreateApplication. Подробнее в официальной документации.