Статьи

Использование токенов единого входа Azure AD для нескольких ресурсов AAD из собственных мобильных приложений

Этот пост является третьим в серии, посвященной проверке подлинности единого входа Azure Active Directory (SSO) в собственных мобильных приложениях.

  1. Аутентификация пользователей приложений iOS с помощью Azure Active Directory
  2. Как лучше всего обрабатывать токены доступа AAD в нативных мобильных приложениях
  3. Использование токенов единого входа Azure для нескольких ресурсов AAD из собственных мобильных приложений (этот пост)
  4. Совместное использование токенов доступа Azure SSO для нескольких собственных мобильных приложений.

Краткое начало

В корпоративном контексте весьма вероятно, что у вас будет несколько веб-сервисов, которые потребляет ваше собственное мобильное приложение. У меня был именно такой сценарий, когда один из моих клиентов спросил, могут ли они поддерживать один и тот же токен в фоновом режиме в мобильном приложении, чтобы использовать его для доступа к нескольким веб-службам. Я провел некоторое время, копаясь в документации и проводя некоторые эксперименты, чтобы подтвердить некоторые моменты. Поэтому в этом посте я хочу поделиться своими выводами о доступе к нескольким ресурсам Azure AD из собственных мобильных приложений с использованием ADAL.

В предыдущих двух статьях мы рассмотрели реализацию входа в единый вход Azure AD в собственных мобильных приложениях , а затем выяснили, как лучше всего поддерживать эти токены доступа . В этой статье рассказывается, как использовать токены единого входа Azure AD для управления доступом к нескольким ресурсам AAD. Давайте предположим, что в Azure есть 2 веб-службы (т. Е. WebApi1 и WebApi2), обе из которых настроены на использование аутентификации Azure AD. Затем у нас есть собственное мобильное приложение, которому требуется доступ к обоим веб-службам (WebApi1 и WebApi2). Давайте посмотрим на то, что мы можем и не можем сделать.

Невозможно использовать один и тот же токен доступа Azure AD для нескольких ресурсов

Первое, что приходит на ум, — это использовать один и тот же токен доступа для нескольких ресурсов Azure AD, о чем и просил клиент. Однако это не разрешено. Azure AD выдает токен для определенного ресурса (который сопоставлен с приложением Azure AD). Когда мы вызываем AcquireToken () , нам нужно предоставить идентификатор ресурса, только ОДИН идентификатор ресурса. Результат будет иметь токен, который может использоваться только для предоставленного ресурса (id). Есть способы, в которых вы можете использовать один и тот же токен (как мы увидим позже в этом посте), но это не рекомендуется, поскольку это усложняет ведение журнала операций, отслеживание процесса аутентификации и т. Д. Поэтому лучше взглянуть на другие опции, предоставляемые Azure и библиотека ADAL.

Используйте Refresh-Token, чтобы получить токены для нескольких ресурсов

Библиотека ADAL поддерживает получение нескольких токенов доступа для нескольких ресурсов с использованием токена обновления. Это означает, что после аутентификации пользователя контекст аутентификации ADAL сможет генерировать токен доступа для нескольких ресурсов без повторной аутентификации пользователя. Это было кратко упомянуто в документации MSDN здесь .

Маркер обновления, выпущенный Azure AD, можно использовать для доступа к нескольким ресурсам. Например, если у вас есть клиентское приложение, которое имеет разрешение на вызов двух веб-API, токен обновления также можно использовать для получения токена доступа к другому веб-API. (Документация MSDN)

public async Task<string> RefreshTokens()
{
    var tokenEntry = await tokensRepository.GetTokens();
    var authorizationParameters = new AuthorizationParameters (_controller);
 
    var result = "Refreshed an existing Token";
    bool hasARefreshToken = true;
 
    if (tokenEntry == null)
    {
 
        var localAuthResult = await _authContext.AcquireTokenAsync (
            resourceId1, clientId, new Uri (redirectUrl), authorizationParameters, UserIdentifier.AnyUser, null);
 
        tokenEntry = new Tokens {
            WebApi1AccessToken = localAuthResult.AccessToken,
            RefreshToken = localAuthResult.RefreshToken,
            Email = localAuthResult.UserInfo.DisplayableId,
            ExpiresOn = localAuthResult.ExpiresOn
        };
        hasARefreshToken = false;
        result = "Acquired a new Token";
    }
 
    var refreshAuthResult = await _authContext.AcquireTokenByRefreshTokenAsync(tokenEntry.RefreshToken, clientId, resourceId2);
    tokenEntry.WebApi2AccessToken = refreshAuthResult.AccessToken;
    tokenEntry.RefreshToken = refreshAuthResult.RefreshToken;
    tokenEntry.ExpiresOn = refreshAuthResult.ExpiresOn;
 
    if (hasARefreshToken)
    {
        // this will only be called when we try refreshing the tokens (not when we are acquiring new tokens.
        refreshAuthResult = await _authContext.AcquireTokenByRefreshTokenAsync (refreshAuthResult.RefreshToken, clientId, resourceId1);
        tokenEntry.WebApi1AccessToken = refreshAuthResult.AccessToken;
        tokenEntry.RefreshToken = refreshAuthResult.RefreshToken;
        tokenEntry.ExpiresOn = refreshAuthResult.ExpiresOn;
    }
 
 
    await tokensRepository.InsertOrUpdateAsync (tokenEntry);
 
    return result;
}

Как видно из вышесказанного, мы проверяем, есть ли у нас токен доступа из предыдущих запусков, и если мы делаем, мы обновляем токены доступа для обеих веб-служб. Обратите внимание, как _authContext.AcquireTokenByRefreshTokenAsync () предоставляет параметр перегрузки, который принимает идентификатор ресурса. Это позволяет нам получить несколько токенов доступа для нескольких ресурсов без повторной аутентификации пользователя. Остальной код похож на то, что мы видели в предыдущих двух постах.

Библиотека ADAL может создавать новые токены для других ресурсов

В предыдущих двух постах мы рассмотрели библиотеку ADAL и то, как она использует TokenCache . Хотя ADAL не поддерживает постоянное кэширование жетонов еще в мобильных приложениях, он все еще использует TokenCache для кэширования в памяти. Это позволяет библиотеке ADAL генерировать новые маркеры доступа, если контекст (AuthenticationContext) все еще существует из предыдущих аутентификаций. Помните, в предыдущем посте мы говорили, что рекомендуется сохранять ссылку на контекст аутентификации? Это очень удобно, поскольку позволяет нам создавать новые маркеры доступа для доступа к нескольким ресурсам Azure AD.

var localAuthResult = await _authContext.AcquireTokenAsync (
            resourceId2, clientId, new Uri (redirectUrl), authorizationParameters, UserIdentifier.AnyUser, null);

Вызов AcquireToken () (даже без обновления-токена) даст нам новый токен доступа к webApi2. Это связано с большим совершенством ADAL, когда он проверяет, есть ли у нас в памяти токен обновления (управляемый ADAL), а затем использует его для генерации нового токена доступа для webApi2.

Альтернатива

Третий альтернативный вариант — самый простой, но не обязательно лучший. В этом случае мы можем использовать один и тот же токен доступа для использования нескольких ресурсов Azure AD. Для этого нам нужно использовать тот же идентификатор приложения Azure AD при настройке аутентификации веб-приложения. Это требует некоторого понимания того, как происходит аутентификация Azure AD в наших веб-приложениях. Если вы обратитесь к учебному пособию Taiseer Joudeh , о котором мы упоминали ранее, вы увидите, что в нашем веб-приложении нам нужно сообщить структуре аутентификации, каковы наши полномочия и аудитория (идентификатор приложения Azure AD). Если мы настроим оба наших веб-приложения на использование одной и той же аудитории (идентификатора приложения Azure AD), а это означает, что мы свяжем их обоих в одно приложение Azure AD, то мы могли бы использовать один и тот же токен доступа для использования обеих веб-служб.

// linking our web app authentication to an Azure AD application
private void ConfigureAuth(IAppBuilder app)
{
    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
            Audience = ConfigurationManager.AppSettings["Audience"],
            Tenant = ConfigurationManager.AppSettings["Tenant"]
        });
}
<appSettings>
    <add key="Tenant" value="hasaltaiargmail.onmicrosoft.com" />
    <add key="Audience" value="http://my-Azure-AD-Application-Id" /> 
</appSettings>

Как мы уже говорили, это очень просто и требует меньше кода, но может вызвать осложнения с точки зрения ведения журнала безопасности и обслуживания. В конце концов, это зависит от вашего контекста и того, чего вы пытаетесь достичь. Поэтому я подумал, что стоит упомянуть, и я оставлю за вами решение, какой вариант вы выберете.

Выводы

Мы рассмотрели, как можно использовать единый вход Azure AD с ADAL для доступа к нескольким ресурсам из собственных мобильных приложений. Как мы видели, есть три основных варианта, и выбор может быть сделан на основе контекста вашего приложения. Я надеюсь, что вы найдете это полезным, и если у вас есть какие-либо вопросы или вам нужна помощь в разработке, которую вы делаете, просто свяжитесь с нами .

Этот пост является третьим в серии, посвященной проверке подлинности единого входа Azure Active Directory (SSO) в собственных мобильных приложениях.