Tutorial: Autenticação de fluxo do Serviço de Aplicativo por meio da API de back-end para o Microsoft Graph

Saiba como criar e configurar um aplicativo do Serviço de Aplicativo de back-end para aceitar a credencial de usuário de um aplicativo front-end e, em seguida, trocar essa credencial por um serviço downstream do Azure. Essa abordagem permite que um usuário entre em um aplicativo do Serviço de Aplicativo de front-end, passe sua credencial para um Serviço de Aplicativo de back-end e acesse um serviço do Azure com a mesma identidade.

Neste tutorial, você aprenderá como:

  • Configure o aplicativo de autenticação de back-end para fornecer um token com escopo para o serviço do Azure a jusante.
  • Use o código JavaScript para trocar o token de acesso do usuário conectado por um novo token para o serviço downstream.
  • Use o código JavaScript para acessar o serviço downstream.

Pré-requisitos

Conclua o tutorial anterior, acesse o Microsoft Graph de um aplicativo JavaScript seguro como usuário, antes de iniciar este tutorial. Não remova os recursos no final do tutorial. Este tutorial pressupõe que você tenha os dois serviços de aplicativo e seus aplicativos de autenticação correspondentes.

O tutorial anterior usou o Azure Cloud Shell como o shell para a CLI do Azure. Este tutorial continua esse uso.

Arquitetura

O tutorial mostra como passar a credencial de usuário fornecida pelo aplicativo front-end para o aplicativo de back-end e, em seguida, para um serviço do Azure. Neste tutorial, o serviço downstream é o Microsoft Graph. A credencial do usuário é usada para obter seu perfil do Microsoft Graph.

Imagem arquitetônica do Serviço de Aplicativo conectando-se ao Serviço de Aplicativo conectando-se ao Microsoft Graph em nome de um usuário conectado.

Fluxo de autenticação para um usuário obter informações do Microsoft Graph nesta arquitetura:

O tutorial anterior cobriu:

  1. Faça login do usuário em um aplicativo front-end configurado para usar o Active Directory como provedor de identidade.
  2. O serviço do aplicativo front-end transmite o token do usuário ao serviço do aplicativo back-end.
  3. O aplicativo de back-end é protegido para permitir que o front-end faça uma solicitação de API. O token de acesso do usuário possui um público-alvo para a API de back-end e um escopo de user_impersonation.
  4. O registro de aplicativo de back-end já tem o Microsoft Graph com o escopo User.Read. Esse escopo é adicionado por padrão a todos os registros de aplicativo.
  5. No final do tutorial anterior, um perfil falso foi retornado ao aplicativo front-end porque o Graph não estava conectado.

Este tutorial estende a arquitetura:

  1. Conceda o consentimento do administrador para que o aplicativo de back-end pule a tela de consentimento do usuário.
  2. Altere o código do aplicativo para converter o token de acesso enviado do aplicativo front-end em um token de acesso com a permissão necessária para o Microsoft Graph.
  3. Forneça o código para que o aplicativo de back-end compartilhar token atual por um novo token com escopo para serviços do Azure a jusante, como o Microsoft Graph.
  4. Forneça o código para que o aplicativo de back-end utilize o novo token para acessar o serviço downstream na qualidade do usuário atualmente autenticado.
  5. Reimplantar aplicativo de back-end com az webapp up.
  6. No final deste tutorial, um perfil real é retornado ao aplicativo front-end porque o Graph está conectado.

Este tutorial não:

  • Altere o aplicativo front-end do tutorial anterior.
  • Altere a permissão de escopo do aplicativo de autenticação de back-end, pois User.Read é adicionado por padrão a todos os aplicativos de autenticação.

No tutorial anterior, quando o usuário entra no aplicativo front-end, uma janela pop-up solicita o consentimento do usuário.

Neste tutorial, para ler o perfil de usuário do Microsoft Graph, o aplicativo de back-end precisa trocar o token de acesso do usuário conectado por um novo token de acesso com as permissões necessárias para o Microsoft Graph. Como o usuário não está conectado diretamente ao aplicativo de back-end, ele não pode acessar a tela de consentimento interativamente. Você deve contornar esse problema configurando o registro do aplicativo back-end no Microsoft Entra ID para conceder consentimento de administrador. Um administrador do Microsoft Entra geralmente faz essa alteração de configuração.

  1. Abra o Portal do Azure e procure o recurso do Serviço de Aplicativo de back-end.

  2. Localize a seção Configurações>Autenticação.

  3. Selecione o provedor de identidade para acessar o aplicativo de autenticação.

  4. No aplicativo de autenticação, selecione Gerenciar>permissões de API.

  5. Selecione Conceder consentimento do administrador para o Diretório Padrão.

    Captura de tela do aplicativo de autenticação do portal do Azure com o botão de consentimento do administrador realçado.

  6. Na janela pop-up, selecione Sim para confirmar o consentimento.

  7. Verifique se a coluna Status diz Concedido para Diretório Padrão. Com essa configuração, o aplicativo de back-end não é mais necessário para mostrar uma tela de consentimento para o usuário conectado e pode solicitar diretamente um token de acesso. O usuário conectado tem acesso à configuração do escopo de User.Read porque esse é o escopo padrão com o qual o registro da aplicação é criado.

    Captura de tela do aplicativo de autenticação do portal do Azure com o consentimento do administrador concedido na coluna de status.

2. Instalar pacotes npm

No tutorial anterior, o aplicativo de back-end não precisava de nenhum pacote npm para autenticação porque a única autenticação foi fornecida configurando o provedor de identidade no portal do Azure. Neste tutorial, o token de acesso do usuário conectado para a API de back-end deve ser trocado por um token de acesso com o Microsoft Graph em seu escopo. Esse intercâmbio é concluído com duas bibliotecas porque esse intercâmbio não utiliza mais a autenticação do Serviço de Aplicativo. Em vez disso, ele usa Microsoft Entra ID e MSAL.js diretamente.

  1. Abra o Azure Cloud Shell e mude para o aplicativo de back-end do diretório de exemplo:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. Instale o pacote npm da MSAL (Biblioteca de Autenticação da Microsoft) do Azure:

    npm install @azure/msal-node
    
  3. Instale o pacote npm do Microsoft Graph:

    npm install @microsoft/microsoft-graph-client
    

3. Adicionar código para trocar o token atual pelo token do Microsoft Graph

O código-fonte para concluir esta etapa é fornecido para você. Siga estas etapas para incluí-lo.

  1. Abra o arquivo ./src/server.js.

  2. Remova a marca de comentário da dependência a seguir no topo do arquivo:

    import { getGraphProfile } from './with-graph/graph';
    
  3. No mesmo arquivo, descompacte a graphProfile variável:

    let graphProfile={};
    
  4. No mesmo arquivo, remova a marca de comentário das seguintes getGraphProfile linhas na rota get-profile para obter o perfil do 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. Salve as alterações: Ctrl + s.

  6. Reimplantar o aplicativo de back-end:

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

4. Inspecione o código de back-end para intercambiar o token de API de back-end pelo token do Microsoft Graph

Para substituir o token de público da API de back-end por um token do Microsoft Graph, o aplicativo de back-end precisa localizar o ID do locatário e utilizá-lo como parte do objeto de configuração do MSAL.js. Como o aplicativo de back-end está configurado com a Microsoft como o provedor de identidade, a ID do Locatário e vários outros valores necessários já estão nas configurações do App Service.

O código a seguir é fornecido para você no aplicativo de exemplo. Você precisa entender por que ele está lá e como ele funciona para que você possa aplicar esse trabalho a outros aplicativos que você cria que precisam dessa mesma funcionalidade.

Inspecionar o código para obter a ID do Locatário

  1. Abra o arquivo ./backend/src/with-graph/auth.js.

  2. Examine a getTenantId() função.

    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. Essa função obtém a ID do locatário atual da WEBSITE_AUTH_OPENID_ISSUER variável de ambiente. O ID é extraído da variável com uma expressão regular.

Inspecionar o código para obter o token do Graph usando MSAL.js

  1. No arquivo ./backend/src/with-graph/auth.js, revise a função getGraphToken().

  2. Crie o objeto de configuração MSAL.js. Use a configuração MSAL para criar o clientCredentialAuthority. Configure a solicitação em nome de. Em seguida, use o acquireTokenOnBehalfOf para trocar o token de acesso da API de back-end por um token de acesso do 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. Inspecionar o código de back-end para acessar o Microsoft Graph com o novo token

Para acessar o Microsoft Graph como um usuário conectado ao aplicativo front-end, as alterações incluem:

  • A configuração do registro de aplicativo do Active Directory com uma permissão de API para o serviço downstream, do Microsoft Graph, com o escopo necessário de User.Read.
  • Conceda o consentimento do administrador para que o aplicativo de back-end pule a tela de consentimento do usuário.
  • Altera o código do aplicativo para converter o token de acesso enviado do aplicativo de front-end em um token de acesso com a permissão necessária para o serviço downstream, do Microsoft Graph.

Agora que o código tem o token correto para o Microsoft Graph, use-o para criar um cliente para o Microsoft Graph e, em seguida, obtenha o perfil do usuário.

  1. Abra o ./backend/src/graph.js

  2. Na função getGraphProfile(), obtenha o token, depois o cliente autenticado a partir do token e, por fim, obtenha o perfil.

    // 
    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. Testar suas alterações

  1. Utilize a interface front-end do site em um navegador web. Talvez seja necessário atualizar o token se ele tiver expirado.

  2. Selecione Get user's profile. Isso transmite sua autenticação no token de portador para o back-end.

  3. O backend responde com o perfil real do Microsoft Graph para sua conta.

    Captura de tela do navegador da web mostrando o aplicativo front-end após obter com sucesso o perfil real do aplicativo back-end.

7. Limpar

Nas etapas anteriores, você criou os recursos do Azure em um grupo de recursos.

  1. Para excluir o grupo de recursos, execute o comando a seguir no Cloud Shell. Esse comando pode levar alguns minutos para ser executado.

    az group delete --name myAuthResourceGroup
    
  2. Use as IDs de cliente que você encontrou e anotou anteriormente nas seções Enable authentication and authorization relativas aos aplicativos de back-end e front-end.

  3. Excluir os registros de aplicativos, tanto para aplicativos front-end quanto para back-end.

    # delete app - do this for both front-end and back-end client ids
    az ad app delete --id <client-id>
    

Perguntas frequentes

Eu tenho um erro 80049217, o que significa?

Esse erro, CompactToken parsing failed with error code: 80049217, significa que o Serviço de Aplicativo de back-end não está autorizado a retornar o token Microsoft Graph. Esse erro é causado porque o registro do aplicativo não tem a User.Read permissão.

Eu tenho um erro AADSTS65001, o que significa?

Esse erro 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 resourcesignifica que o aplicativo de autenticação de back-end não foi configurado para consentimento do administrador. Como o erro aparece no log do aplicativo de back-end, o aplicativo de front-end não consegue informar ao usuário por que ele não viu seu perfil no aplicativo de front-end.

Como fazer para me conectar a um serviço do Azure downstream diferente como usuário?

Este tutorial demonstra um aplicativo de API autenticado no Microsoft Graph. As mesmas etapas gerais podem ser aplicadas para acessar qualquer serviço do Azure em nome do usuário.

  1. Nenhuma alteração no aplicativo front-end. Somente alterações no registro do aplicativo de autenticação do back-end e no código-fonte do aplicativo de back-end.
  2. Troque o token do usuário, válido apenas para a API de back-end, por um token para o serviço de destino ao qual você deseja acessar.
  3. Use o token no SDK do serviço downstream para criar um cliente.
  4. Use o cliente downstream para acessar a funcionalidade do serviço.