Поделиться через


Краткое руководство. Вход пользователей и вызов API Microsoft Graph из приложения Android

Добро пожаловать! Это, вероятно, не страница, которую вы ожидали. Сейчас мы работаем над исправлением, но на данный момент используйте следующую ссылку:

Краткое руководство. Вход пользователей и вызов Microsoft Graph из приложения Android

Приносим извинения за неудобства и благодарим за терпение! Мы работаем над устранением этой проблемы.

В этом кратком руководстве вы скачаете и запустите пример кода, демонстрирующий, как в приложении Android реализовать вход пользователей и получить токен доступа для вызова API Microsoft Graph.

Иллюстрацию см. в разделе Как работает этот пример.

Приложения должны быть представлены объектом приложения в Microsoft Entra ID, чтобы платформа удостоверений Майкрософт могла предоставлять токены вашему приложению.

Предпосылки

Шаг 1. Настройка приложения на портале Azure

Чтобы пример кода в этом кратком руководстве работал, добавьте URI перенаправления , совместимый с брокером Проверки подлинности.

Уже настроено Приложение настроено с помощью этих атрибутов

Шаг 2. Скачивание проекта

Запустите проект с помощью Android Studio.

Шаг 3. Приложение настроено и готово к выполнению

Мы уже настроили для проекта нужные значения свойств приложения, и его можно запускать. Пример приложения запускается на экране Single Account Mode (Режим единой учетной записи). Область по умолчанию, user.read, предоставляется по умолчанию и используется при чтении данных собственного профиля во время вызова API Microsoft Graph. URL-адрес для вызова Microsoft Graph API предоставляется по умолчанию. При необходимости их можно изменить.

Пример приложения MSAL с одним и несколькими учетными записями

Используйте меню приложения для переключения между режимами одной и нескольких учетных записей.

В режиме одной учетной записи войдите с помощью рабочей или домашней учетной записи:

  1. Выберите Get graph data interactively (Получить данные графов в интерактивном режиме ), чтобы запросить у пользователя учетные данные. Вы увидите выходные данные вызова API Microsoft Graph в нижней части экрана.
  2. После входа в систему выберите Get graph data silently (Получить данные графов без уведомления), чтобы вызвать Microsoft Graph API, не запрашивая у пользователя учетные данные снова. Вы увидите выходные данные вызова API Microsoft Graph в нижней части экрана.

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

Замечание

Enter_the_Supported_Account_Info_Here

Как работает этот пример

Снимок экрана: пример приложения

Код разделен на фрагменты, демонстрирующие, как записывать приложение MSAL для одной и нескольких учетных записей. Файлы кода организованы следующим образом:

Файл Демонстрирует
MainActivity Управляет пользовательским интерфейсом
Упаковщик запросов MS Graph Вызывает API Microsoft Graph, используя токен, предоставленный MSAL
ФрагментРежимаМножественныхАккаунтов Инициализирует приложение с несколькими учетными записями, загружает учетную запись пользователя и получает токен для вызова API Microsoft Graph
SingleAccountModeFragment Инициализирует приложение с одной учетной записью, загружает учетную запись пользователя и получает токен для вызова API Microsoft Graph
res/auth_config_multiple_account.json Файл конфигурации нескольких учетных записей
res/auth_config_single_account.json Файл конфигурации одной учетной записи
Скрипты Gradle/build.grade (модуль: app) Здесь добавляются зависимости библиотеки MSAL

Теперь мы рассмотрим эти файлы подробнее и вызовем код, относящийся к MSAL, в каждом из них

Добавление MSAL в приложение

MSAL (com.microsoft.identity.client) — это библиотека, используемая для входа пользователей и запроса токенов для доступа к API, защищенному платформой идентификации Microsoft. Gradle 3.0+ устанавливает библиотеку при добавлении в файл Скрипты Gradle>build.gradle (модуль: app) в разделе Зависимости следующего фрагмента кода:

dependencies {
    ...
    implementation 'com.microsoft.identity.client:msal:2.+'
    ...
}

Он указывает Gradle загрузить и создать MSAL из Maven Central.

Кроме того, необходимо добавить ссылки на maven в часть allprojects>repositoriesфайла build.gradle (Module: app), как показано ниже.

allprojects {
    repositories {
        mavenCentral()
        google()
        mavenLocal()
        maven {
            url 'https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1'
        }
        maven {
            name "vsts-maven-adal-android"
            url "https://identitydivision.pkgs.visualstudio.com/_packaging/AndroidADAL/maven/v1"
            credentials {
                username System.getenv("ENV_VSTS_MVN_ANDROIDADAL_USERNAME") != null ? System.getenv("ENV_VSTS_MVN_ANDROIDADAL_USERNAME") : project.findProperty("vstsUsername")
                password System.getenv("ENV_VSTS_MVN_ANDROIDADAL_ACCESSTOKEN") != null ? System.getenv("ENV_VSTS_MVN_ANDROIDADAL_ACCESSTOKEN") : project.findProperty("vstsMavenAccessToken")
            }
        }
        jcenter()
    }
}

Импорт MSAL

Импорты, относящиеся к библиотеке MSAL, — com.microsoft.identity.client.*. Например, вы увидите import > com.microsoft.identity.client.PublicClientApplication;, что является пространством имен для класса PublicClientApplication, который представляет общедоступное клиентское приложение.

SingleAccountModeFragment.java

В этом файле показано, как создать приложение MSAL для одной учетной записи и вызвать API Microsoft Graph.

Приложения с одной учетной записью используются только одним пользователем. Например, у вас может быть только одна учетная запись для входа в приложение сопоставления.

Инициализация одной учетной записи в MSAL

В auth_config_single_account.json, в onCreateView(), одна учетная запись PublicClientApplication создается на основе сведений о конфигурации, хранящихся в файле auth_config_single_account.json. Таким образом вы инициализируете библиотеку MSAL для использования в приложении MSAL с одной учетной записью:

...
// Creates a PublicClientApplication object with res/raw/auth_config_single_account.json
PublicClientApplication.createSingleAccountPublicClientApplication(getContext(),
        R.raw.auth_config_single_account,
        new IPublicClientApplication.ISingleAccountApplicationCreatedListener() {
            @Override
            public void onCreated(ISingleAccountPublicClientApplication application) {
                /**
                 * This test app assumes that the app is only going to support one account.
                 * This requires "account_mode" : "SINGLE" in the config json file.
                 **/
                mSingleAccountApp = application;
                loadAccount();
            }

            @Override
            public void onError(MsalException exception) {
                displayError(exception);
            }
        });

Вход пользователя

В файле SingleAccountModeFragment.java код для входа пользователя находится в initializeUI() в обработчике щелчков signInButton.

Прежде чем пытаться получить токены, вызовите signIn(). signIn() ведет себя так, как будто вызывается acquireToken(), в результате чего пользователь получает интерактивный запрос на вход.

Вход пользователя является асинхронной операцией. Передается метод для обратного вызова, который вызывает API Microsoft Graph и обновляет пользовательский интерфейс после входа пользователя:

mSingleAccountApp.signIn(getActivity(), null, getScopes(), getAuthInteractiveCallback());

Выйти из учетной записи пользователя

В файле SingleAccountModeFragment.java код для выхода пользователя находится в initializeUI() в обработчике щелчков signOutButton. Выход пользователя является асинхронной операцией. При выходе пользователя также очищается кеш токена для этой учетной записи. Для обновления пользовательского интерфейса после выхода из учетной записи пользователя создается обратный вызов:

mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback() {
    @Override
    public void onSignOut() {
        updateUI(null);
        performOperationOnSignOut();
    }

    @Override
    public void onError(@NonNull MsalException exception) {
        displayError(exception);
    }
});

Получение токена в интерактивном режиме или в фоновом режиме

Чтобы представить пользователю минимальное количество запросов, вы обычно получаете токен незаметно. Затем, если возникла ошибка, попробуйте получить токен интерактивно. Когда приложение вызывает signIn() впервые, оно фактически действует как вызов acquireToken(), который запрашивает учетные данные пользователя.

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

  • Первый вход пользователя в приложение.
  • Если пользователь сбрасывает пароль, ему потребуется ввести свои учетные данные.
  • Если отменяется согласие.
  • Приложение явно требует согласия.
  • Когда приложение запрашивает доступ к ресурсу в первый раз
  • Если требуется многофакторная проверка подлинности или другие политики условного доступа

Код для интерактивного получения токена (то есть с помощью пользовательского интерфейса) находится в файле SingleAccountModeFragment.java в initializeUI() в обработчике щелчков callGraphApiInteractiveButton:

/**
 * If acquireTokenSilent() returns an error that requires an interaction (MsalUiRequiredException),
 * invoke acquireToken() to have the user resolve the interrupt interactively.
 *
 * Some example scenarios are
 *  - password change
 *  - the resource you're acquiring a token for has a stricter set of requirement than your Single Sign-On refresh token.
 *  - you're introducing a new scope which the user has never consented for.
 **/
mSingleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());

Если пользователь уже выполнил вход, acquireTokenSilentAsync() приложения могут автоматически запрашивать маркеры, как показано в >initializeUI()обработчике щелчка callGraphApiSilentButton :

/**
 * Once you've signed the user in,
 * you can perform acquireTokenSilent to obtain resources without interrupting the user.
 **/
  mSingleAccountApp.acquireTokenSilentAsync(getScopes(), AUTHORITY, getAuthSilentCallback());

Загрузка учетной записи

Код для загрузки учетной записи находится в файле SingleAccountModeFragment.java в loadAccount(). Загрузка учетной записи пользователя является асинхронной операцией, поэтому обратные вызовы для обработки при загрузке учетной записи, изменении или возникновении ошибки передаются в MSAL. Следующий код также обрабатывает onAccountChanged(), что происходит при удалении учетной записи, переходе пользователя на другую учетную запись и т. д.

private void loadAccount() {
    ...

    mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback() {
        @Override
        public void onAccountLoaded(@Nullable IAccount activeAccount) {
            // You can use the account data to update your UI or your app database.
            updateUI(activeAccount);
        }

        @Override
        public void onAccountChanged(@Nullable IAccount priorAccount, @Nullable IAccount currentAccount) {
            if (currentAccount == null) {
                // Perform a cleanup task as the signed-in account changed.
                performOperationOnSignOut();
            }
        }

        @Override
        public void onError(@NonNull MsalException exception) {
            displayError(exception);
        }
    });

Вызов Microsoft Graph

Когда пользователь выполнил вход, вызов Microsoft Graph выполняется через HTTP-запрос с помощью callGraphAPI(), определенного в файле SingleAccountModeFragment.java. Эта функция представляет собой программу-оболочку, которая упрощает пример, выполняя некоторые задачи, такие как получение маркера доступа из authenticationResult, упаковка вызова MSGraphRequestWrapper и отображение результатов вызова.

private void callGraphAPI(final IAuthenticationResult authenticationResult) {
    MSGraphRequestWrapper.callGraphAPIUsingVolley(
            getContext(),
            graphResourceTextView.getText().toString(),
            authenticationResult.getAccessToken(),
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    /* Successfully called graph, process data and send to UI */
                    ...
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    ...
                }
            });
}

auth_config_single_account.json

Это файл конфигурации для приложения MSAL, использующего одну учетную запись.

Описание этих полей см. в статье Understand the Android MSAL configuration file (Файл конфигурации библиотеки проверки подлинности Microsoft для Android (MSAL)).

Обратите внимание на присутствие "account_mode" : "SINGLE", который настраивает это приложение для использования одной учетной записи.

Параметр "client_id" предварительно настроен для использования регистрации объекта приложения, которую обслуживает корпорация Майкрософт. Параметр "redirect_uri" предварительно настроен для использования ключа подписывания, предоставленного в примере кода.

{
  "client_id" : "00001111-aaaa-2222-bbbb-3333cccc4444",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
  "account_mode" : "SINGLE",
  "broker_redirect_uri_registered": true,
  "authorities" : [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADandPersonalMicrosoftAccount",
        "tenant_id": "common"
      }
    }
  ]
}

MultipleAccountModeFragment.java

В этом файле показано, как создать приложение MSAL с несколькими учетными записями и вызвать API Microsoft Graph.

Примером приложения с несколькими учетными записями является почтовое приложение, которое позволяет работать с несколькими учетными записями пользователей, такими как рабочая и личная учетная запись.

Инициализация MSAL нескольких учетных записей

В файле MultipleAccountModeFragment.java в onCreateView() объект приложения с несколькими учетными записями (IMultipleAccountPublicClientApplication) создается с использованием сведений о конфигурации, хранящихся в auth_config_multiple_account.json file:

// Creates a PublicClientApplication object with res/raw/auth_config_multiple_account.json
PublicClientApplication.createMultipleAccountPublicClientApplication(getContext(),
        R.raw.auth_config_multiple_account,
        new IPublicClientApplication.IMultipleAccountApplicationCreatedListener() {
            @Override
            public void onCreated(IMultipleAccountPublicClientApplication application) {
                mMultipleAccountApp = application;
                loadAccounts();
            }

            @Override
            public void onError(MsalException exception) {
                ...
            }
        });

Созданный объект MultipleAccountPublicClientApplication хранится в переменной члена класса, чтобы его можно было использовать для взаимодействия с библиотекой MSAL для получения токенов, загрузки и удаления учетной записи пользователя.

Загрузка учетной записи

Приложения с несколькими учетными записями обычно вызывают getAccounts(), чтобы выбрать учетную запись для использования в операциях MSAL. Код для загрузки учетной записи находится в файле MultipleAccountModeFragment.java в loadAccounts(). Загрузка учетной записи пользователя является асинхронной операцией. Поэтому обратный вызов обрабатывает ситуации, когда учетная запись загружается, изменяется или возникает ошибка.

/**
 * Load currently signed-in accounts, if there's any.
 **/
private void loadAccounts() {
    if (mMultipleAccountApp == null) {
        return;
    }

    mMultipleAccountApp.getAccounts(new IPublicClientApplication.LoadAccountsCallback() {
        @Override
        public void onTaskCompleted(final List<IAccount> result) {
            // You can use the account data to update your UI or your app database.
            accountList = result;
            updateUI(accountList);
        }

        @Override
        public void onError(MsalException exception) {
            displayError(exception);
        }
    });
}

Получение токена в интерактивном или в фоновом режиме

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

  • При первом входе пользователей в приложение
  • Если пользователь сбрасывает пароль, ему потребуется ввести свои учетные данные.
  • Если отменяется согласие.
  • Приложение явно требует согласия.
  • Когда приложение запрашивает доступ к ресурсу в первый раз
  • Если требуется многофакторная проверка подлинности или другие политики условного доступа

Приложения с несколькими учетными записями обычно должны получать токены в интерактивном режиме, то есть в пользовательском интерфейсе, с вызовом acquireToken(). Код для интерактивного получения токена находится в файле MultipleAccountModeFragment.java в initializeUI> () в обработчике щелчков callGraphApiInteractiveButton:

/**
 * Acquire token interactively. It will also create an account object for the silent call as a result (to be obtained by > getAccount()).
 *
 * If acquireTokenSilent() returns an error that requires an interaction,
 * invoke acquireToken() to have the user resolve the interrupt interactively.
 *
 * Some example scenarios are
 *  - password change
 *  - the resource you're acquiring a token for has a stricter set of requirement than your SSO refresh token.
 *  - you're introducing a new scope which the user has never consented for.
 **/
mMultipleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());

Приложения не требуют, чтобы пользователи выполняли вход каждый раз при запросе токена. Если пользователь уже выполнил вход, acquireTokenSilentAsync() позволяет приложениям запрашивать токены без запроса к пользователю, как показано в файле MultipleAccountModeFragment.java в initializeUI() в обработчике щелчков callGraphApiSilentButton:

/**
 * Performs acquireToken without interrupting the user.
 *
 * This requires an account object of the account you're obtaining a token for.
 * (can be obtained via getAccount()).
 */
mMultipleAccountApp.acquireTokenSilentAsync(getScopes(),
    accountList.get(accountListSpinner.getSelectedItemPosition()),
    AUTHORITY,
    getAuthSilentCallback());

Удаление учетной записи

Код для удаления учетной записи и всех кэшированных токенов для учетной записи находится в файле MultipleAccountModeFragment.java в initializeUI() в обработчике кнопки удаления учетной записи. Прежде чем вы сможете удалить учетную запись, вам нужен объект учетной записи, который вы получаете из методов MSAL, таких как getAccounts() и acquireToken(). Так как удаление учетной записи является асинхронной операцией, обратный вызов onRemoved предоставляется для обновления пользовательского интерфейса.

/**
 * Removes the selected account and cached tokens from this app (or device, if the device is in shared mode).
 **/
mMultipleAccountApp.removeAccount(accountList.get(accountListSpinner.getSelectedItemPosition()),
        new IMultipleAccountPublicClientApplication.RemoveAccountCallback() {
            @Override
            public void onRemoved() {
                ...
                /* Reload account asynchronously to get the up-to-date list. */
                loadAccounts();
            }

            @Override
            public void onError(@NonNull MsalException exception) {
                displayError(exception);
            }
        });

auth_config_multiple_account.json

Это файл конфигурации для приложения MSAL, которое использует несколько учетных записей.

См. статью Understand the Android MSAL configuration file для объяснения различных полей.

В отличие от файла конфигурации auth_config_single_account.json, в этом файле конфигурации указано "account_mode" : "MULTIPLE" вместо "account_mode" : "SINGLE", так как это приложение с несколькими учетными записями.

Параметр "client_id" предварительно настроен для использования регистрации объекта приложения, которую обслуживает корпорация Майкрософт. Параметр "redirect_uri" предварительно настроен для использования ключа подписывания, предоставленного в примере кода.

{
  "client_id" : "00001111-aaaa-2222-bbbb-3333cccc4444",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
  "account_mode" : "MULTIPLE",
  "broker_redirect_uri_registered": true,
  "authorities" : [
    {
      "type": "AAD",
      "audience": {
        "type": "AzureADandPersonalMicrosoftAccount",
        "tenant_id": "common"
      }
    }
  ]
}

Помощь и поддержка

Если вам нужна помощь, хотите сообщить о проблеме или узнать о доступных вариантах поддержки, см. Справка и поддержка для разработчиков.

Дальнейшие действия

Перейдите к учебнику по Android, с помощью которого вы создадите приложение Android, получающее маркер доступа от платформы удостоверений Майкрософт и использующее его для вызова API Microsoft Graph.