Руководство. Поток проверки подлинности из Служба приложений через внутренний API в Microsoft Graph

Узнайте, как создать и настроить серверную службу приложений, чтобы принять учетные данные пользователя внешнего приложения, а затем обменять эти учетные данные для нижестоящей службы Azure. Это позволяет пользователю войти в службу интерфейсных приложений, передать свои учетные данные в серверную службу приложений, а затем получить доступ к службе Azure с тем же удостоверением.

В этом руководстве описано следующее:

  • Настройте серверное приложение проверки подлинности для предоставления маркера область для нижестоящей службы Azure.
  • Используйте код JavaScript для обмена маркером доступа пользователя, вошедшего в систему, на новый маркер для нижестоящей службы.
  • Используйте код JavaScript для доступа к нижестоящей службе.

Необходимые компоненты

Выполните предыдущее руководство. Доступ к Microsoft Graph из защищенного приложения JavaScript от имени пользователя перед началом работы с этим руководством, но не удаляйте ресурсы в конце руководства. В этом руководстве предполагается, что у вас есть две службы приложений и соответствующие приложения проверки подлинности.

Предыдущее руководство использовало Azure Cloud Shell в качестве оболочки для Azure CLI. В этом руководстве продолжается использование.

Архитектура

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

Architectural image of App Service connecting to App Service connecting to Microsoft Graph on behalf of a signed-in user.

Поток проверки подлинности для пользователя, чтобы получить сведения о Microsoft Graph в этой архитектуре:

В предыдущем руководстве описано:

  1. Войдите в службу интерфейсных приложений, настроенную для использования Active Directory в качестве поставщика удостоверений.
  2. Служба интерфейсных приложений передает маркер пользователя в серверную службу приложений.
  3. Серверное приложение защищено, чтобы разрешить интерфейсу выполнять запрос API. Маркер доступа пользователя имеет аудиторию для внутреннего API и областьuser_impersonation.
  4. Регистрация серверного приложения уже имеет Microsoft Graph с областьUser.Read. Это добавляется по умолчанию ко всем регистрациям приложений.
  5. В конце предыдущего руководства поддельный профиль был возвращен в интерфейсное приложение, так как Graph не был подключен.

В этом руководстве расширена архитектура:

  1. Предоставьте администратору согласие на обход экрана согласия пользователя для внутреннего приложения.
  2. Измените код приложения, чтобы преобразовать маркер доступа, отправленный из внешнего приложения, в маркер доступа с необходимым разрешением для Microsoft Graph.
  3. Предоставьте код для маркера обмена серверным приложением для нового маркера с область нижестоящей службы Azure, например Microsoft Graph.
  4. Предоставьте код, чтобы серверное приложение использовало новый маркер для доступа к нижестоящей службе в качестве текущего пользователя проверки подлинности.
  5. Повторное развертывание серверного приложения с az webapp upпомощью .
  6. В конце этого руководства реальный профиль возвращается в интерфейсное приложение, так как Graph подключен.

В этом руководстве нет:

  • Измените интерфейсные приложения из предыдущего руководства.
  • Измените разрешение область серверной проверки подлинности, так как User.Read по умолчанию добавляется ко всем приложениям проверки подлинности.

В предыдущем руководстве, когда пользователь вошел в интерфейсное приложение, появится всплывающее окно с запросом согласия пользователя.

В этом руководстве для чтения профиля пользователя из Microsoft Graph серверное приложение должно обменять маркер доступа вошедшего пользователя на новый маркер доступа с необходимыми разрешениями для Microsoft Graph. Так как пользователь не подключен непосредственно к внутреннему приложению, он не может получить доступ к экрану согласия в интерактивном режиме. Для этого необходимо настроить регистрацию приложения серверного приложения в идентификаторе Microsoft Entra ID, чтобы предоставить согласие администратора. Это изменение параметра обычно выполняется администратором Active Directory.

  1. Откройте портал Azure и выполните поиск исследований для серверной Служба приложений.

  2. Найдите раздел Параметры —> проверка подлинности.

  3. Выберите поставщика удостоверений, чтобы перейти к приложению проверки подлинности.

  4. В приложении проверки подлинности выберите "Управление —> разрешения API".

  5. Выберите "Предоставить согласие администратора" для каталога по умолчанию.

    Screenshot of Azure portal authentication app with admin consent button highlighted.

  6. Во всплывающем окне выберите "Да ", чтобы подтвердить согласие.

  7. Проверьте столбец "Состояние" с сообщением "Предоставлено для каталога по умолчанию". С помощью этого параметра серверное приложение больше не требуется для отображения экрана согласия для пользователя, вошедшего в систему, и может напрямую запросить маркер доступа. Пользователь, вошедшего в систему, имеет доступ к User.Read параметру область, так как это область по умолчанию, с помощью которого создается регистрация приложения.

    Screenshot of Azure portal authentication app with admin consent granted in status column.

2. Установка пакетов npm

В предыдущем руководстве серверное приложение не нуждалось в пакетах npm для проверки подлинности, так как была предоставлена только проверка подлинности путем настройки поставщика удостоверений в портал Azure. В этом руководстве маркер доступа пользователя, вошедшего в систему для внутреннего API, необходимо обменять на маркер доступа с Помощью Microsoft Graph в область. Этот обмен завершается двумя библиотеками, так как этот обмен больше не использует проверку подлинности Служба приложений, но идентификатор Microsoft Entra и MSAL.js напрямую.

  1. Откройте Azure Cloud Shell и измените его в серверном приложении каталога:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. Установите пакет npm для Azure MSAL:

    npm install @azure/msal-node
    
  3. Установите пакет npm Microsoft Graph:

    npm install @microsoft/microsoft-graph-client
    

3. Добавление кода для обмена текущим маркером для токена Microsoft Graph

Исходный код для выполнения этого шага предоставляется для вас. Чтобы включить его, выполните следующие действия.

  1. Откройте файл ./src/server.js.

  2. Раскомментируйте следующую зависимость в верхней части файла:

    import { getGraphProfile } from './with-graph/graph';
    
  3. В том же файле раскомментируйте graphProfile переменную:

    let graphProfile={};
    
  4. В том же файле раскомментируйте следующие getGraphProfile строки маршрута get-profile , чтобы получить профиль из Microsoft Graph:

    // where did the profile come from
    profileFromGraph=true;
    
    // get the profile from Microsoft Graph
    graphProfile = await getGraphProfile(accessToken);
    
    // log the profile for debugging
    console.log(`profile: ${JSON.stringify(graphProfile)}`);
    
  5. Сохраните изменения: CTRL + s.

  6. Повторное развертывание серверного приложения:

    az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> 
    
    

4. Проверьте внутренний код для обмена маркером API серверной части для маркера Microsoft Graph

Чтобы изменить маркер аудитории API серверной части для маркера Microsoft Graph, серверное приложение должно найти идентификатор клиента и использовать его в рамках объекта конфигурации MSAL.js. Так как серверное приложение с настроенным с помощью Корпорации Майкрософт в качестве поставщика удостоверений идентификатор клиента и несколько других обязательных значений уже находятся в параметрах приложения службы приложений.

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

Проверка кода для получения идентификатора клиента

  1. Откройте файл ./backend/src/with-graph/auth.js.

  2. Просмотрите функцию getTenantId() .

    export function getTenantId() {
    
        const openIdIssuer = process.env.WEBSITE_AUTH_OPENID_ISSUER;
        const backendAppTenantId = openIdIssuer.replace(/https:\/\/sts\.windows\.net\/(.{1,36})\/v2\.0/gm, '$1');
    
        return backendAppTenantId;
    }
    
  3. Эта функция получает текущий идентификатор клиента из переменной WEBSITE_AUTH_OPENID_ISSUER среды. Идентификатор анализируется из переменной с регулярным выражением.

Проверка кода для получения маркера Graph с помощью MSAL.js

  1. Все еще в файле просмотрите ./backend/src/with-graph/auth.js функцию getGraphToken() .

  2. Создайте объект конфигурации MSAL.js, используйте конфигурацию MSAL для создания clientCredentialAuthority. Настройте запрос от имени. Затем используйте метод acquireTokenOnBehalfOf для обмена маркером доступа внутреннего API для маркера доступа Graph.

    // ./backend/src/auth.js
    // Exchange current bearerToken for Graph API token
    // Env vars were set by App Service
    export async function getGraphToken(backEndAccessToken) {
    
        const config = {
            // MSAL configuration
            auth: {
                // the backend's authentication CLIENT ID 
                clientId: process.env.WEBSITE_AUTH_CLIENT_ID,
                // the backend's authentication CLIENT SECRET 
                clientSecret: process.env.MICROSOFT_PROVIDER_AUTHENTICATION_SECRET,
                // OAuth 2.0 authorization endpoint (v2)
                // should be: https://login.microsoftonline.com/BACKEND-TENANT-ID
                authority: `https://login.microsoftonline.com/${getTenantId()}`
            },
            // used for debugging
            system: {
                loggerOptions: {
                    loggerCallback(loglevel, message, containsPii) {
                        console.log(message);
                    },
                    piiLoggingEnabled: true,
                    logLevel: MSAL.LogLevel.Verbose,
                }
            }
        };
    
        const clientCredentialAuthority = new MSAL.ConfidentialClientApplication(config);
    
        const oboRequest = {
            oboAssertion: backEndAccessToken,
            // this scope must already exist on the backend authentication app registration 
            // and visible in resources.azure.com backend app auth config
            scopes: ["https://graph.microsoft.com/.default"]
        }
    
        // This example has App service validate token in runtime
        // from headers that can't be set externally
    
        // If you aren't using App service's authentication, 
        // you must validate your access token yourself
        // before calling this code
        try {
            const { accessToken } = await clientCredentialAuthority.acquireTokenOnBehalfOf(oboRequest);
            return accessToken;
        } catch (error) {
            console.log(`getGraphToken:error.type = ${error.type}  ${error.message}`);
        }
    }
    

5. Проверьте внутренний код для доступа к Microsoft Graph с помощью нового маркера

Чтобы получить доступ к Microsoft Graph в качестве пользователя, вошедшего в интерфейсное приложение, изменения включают:

  • Настройка регистрации приложения Active Directory с разрешением API для нижестоящей службы Microsoft Graph с необходимым областьUser.Read.
  • Предоставьте администратору согласие на обход экрана согласия пользователя для внутреннего приложения.
  • Измените код приложения, чтобы преобразовать маркер доступа, отправленный из внешнего приложения, в маркер доступа с необходимым разрешением для нижестоящей службы Microsoft Graph.

Теперь, когда код имеет правильный маркер для Microsoft Graph, используйте его для создания клиента в Microsoft Graph, а затем получите профиль пользователя.

  1. Откройте ./backend/src/graph.js.

  2. getGraphProfile() В функции получите маркер, а затем прошедший проверку подлинности клиент из маркера, а затем получите профиль.

    // 
    import graph from "@microsoft/microsoft-graph-client";
    import { getGraphToken } from "./auth.js";
    
    // Create client from token with Graph API scope
    export function getAuthenticatedClient(accessToken) {
        const client = graph.Client.init({
            authProvider: (done) => {
                done(null, accessToken);
            }
        });
    
        return client;
    }
    export async function getGraphProfile(accessToken) {
        // exchange current backend token for token with 
        // graph api scope
        const graphToken = await getGraphToken(accessToken);
    
        // use graph token to get Graph client
        const graphClient = getAuthenticatedClient(graphToken);
    
        // get profile of user
        const profile = await graphClient
            .api('/me')
            .get();
    
        return profile;
    }
    

6. Проверка изменений

  1. Используйте внешний веб-сайт в браузере. URL-адрес находится в формате https://<front-end-app-name>.azurewebsites.net/. Возможно, потребуется обновить маркер, если срок его действия истек.

  2. Выберите Get user's profile. Это передает проверку подлинности в маркер носителя серверной части.

  3. Серверная часть отвечает с реальным профилем Microsoft Graph для вашей учетной записи.

    Screenshot of web browser showing frontend application after successfully getting real profile from backend app.

7. Очистка

На предыдущем шаге вы создали ресурсы Azure в группе ресурсов.

  1. Удалите группу ресурсов, выполнив следующую команду в Cloud Shell. Ее выполнение может занять до минуты.

    az group delete --name myAuthResourceGroup
    
  2. Используйте идентификатор клиента приложений проверки подлинности, которые вы ранее нашли и запишите в Enable authentication and authorization разделах для внутренних и интерфейсных приложений.

  3. Удаление регистраций приложений для внешних и внутренних приложений.

    # delete app - do this for both frontend and backend client ids
    az ad app delete <client-id>
    

Часто задаваемые вопросы

Я получил ошибку 80049217, что это означает?

Эта ошибка означает, CompactToken parsing failed with error code: 80049217что серверная служба приложений не авторизована для возврата маркера Microsoft Graph. Эта ошибка вызвана тем, что регистрация приложения отсутствует User.Read разрешение.

Я получил ошибку AADSTS65001, что это означает?

Эта ошибка означает, AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resourceчто серверная проверка подлинности не настроена для Администратор согласия. Так как ошибка отображается в журнале серверного приложения, интерфейсное приложение не может сообщить пользователю, почему он не видел свой профиль в интерфейсном приложении.

Разделы справки подключиться к другой нижестоящей службе Azure в качестве пользователя?

В этом руководстве показано приложение API, прошедшее проверку подлинности в Microsoft Graph, однако для доступа к любой службе Azure от имени пользователя можно применить те же общие шаги.

  1. Нет изменений в интерфейсном приложении. Только изменения в регистрации приложения проверки подлинности серверной части и исходном коде серверного приложения.
  2. Обмен маркером пользователя область для серверного API для маркера в нижестоящей службе, к которой требуется получить доступ.
  3. Используйте маркер в пакете SDK нижестоящей службы для создания клиента.
  4. Используйте подчиненный клиент для доступа к функциям службы.

Следующие шаги