共用方式為


教學課程:透過後端 API 從 App Service 到 Microsoft Graph 的流程驗證

瞭解如何建立和設定後端 App Service 以接受前端應用程式的使用者認證,然後交換下游 Azure 服務的認證。 這可讓使用者登入前端 App Service、將其認證傳遞至後端 App Service,然後存取具有相同身分識別的 Azure 服務。

在本教學課程中,您將瞭解如何:

  • 設定後端驗證應用程式,以提供適用於下游 Azure 服務的令牌範圍
  • 使用 JavaScript 程式代碼來交換已 登入使用者的存取令牌 ,以取得下游服務的新令牌。
  • 使用 JavaScript 程式代碼來存取下游服務。

先決條件

在開始本教學課程之前,請先完成上一個教學課程:從安全的 JavaScript 應用程式存取 Microsoft Graph,但請不要在教學課程結束後移除資源。 本教學課程假設您有兩個應用程式服務及其對應的驗證應用程式。

上一個教學使用 Azure Cloud Shell 作為 Azure CLI 的 Shell。 本教學課程會繼續使用該用法。

建築

本教學課程示範如何將前端應用程式所提供的使用者認證傳遞至後端應用程式,然後傳遞至 Azure 服務。 在本教學課程中,下游服務會是 Microsoft Graph。 用戶的登入憑證可用來從 Microsoft Graph 取得其個人資料。

App Service 連線到 App Service 的架構影像,代表登入的用戶連線到 Microsoft Graph。

使用者在此架構中取得Microsoft Graph 資訊的驗證流程

先前教程 涵蓋:

  1. 將使用者登入配置為使用 Active Directory 作為身分識別提供者的前端應用服務。
  2. 前端 App Service 會將使用者的令牌傳遞至後端 App Service。
  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 入口網站,並搜尋後端 App Service 的研究。

  2. 尋找 [設定 -> 驗證] 區段。

  3. 選取識別提供者以移至驗證應用程式。

  4. 在驗證應用程式中,選取 [ 管理 -> API 許可權]。

  5. 選取 [授與預設目錄的管理員同意]。

    Azure 入口網站驗證應用程式的螢幕快照,其中已醒目提示系統管理員同意按鈕。

  6. 在彈出視窗中,選取 [ ] 以確認同意。

  7. 確認 狀態 欄顯示 已授與預設目錄。 使用此設定時,不再需要後端應用程式向登入的用戶顯示同意畫面,而且可以直接要求存取令牌。 登入的使用者具有範圍設定的 User.Read 存取權,因為這是建立應用程式註冊的預設範圍。

    Azure 入口網站驗證應用程式的螢幕快照,其中狀態欄顯示已授予管理員同意。

2.安裝 npm 套件

在上一個教學課程中,後端應用程式不需要任何 npm 套件進行驗證,因為唯一的驗證是藉由在 Azure 入口網站中設定識別提供者來提供。 在此教學中,必須將已登入使用者的後端 API 存取令牌交換為具有 Microsoft Graph 範圍的存取令牌。 此交換已完成使用兩個程式庫,因為此交換已不再使用 App Service 驗證,而是改為使用 Microsoft Entra ID 和 MSAL.js。

  1. 開啟 Azure Cloud Shell 並變更為範例目錄的後端應用程式:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. 安裝 Azure MSAL npm 套件:

    npm install @azure/msal-node
    
  3. 安裝 Microsoft Graph npm 套件:

    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 令牌

若要變更 Microsoft Graph 令牌的後端 API 物件令牌,後端應用程式必須尋找租使用者標識碼,並將該標識碼當做 MSAL.js 組態物件的一部分使用。 由於後端應用程式已將 Microsoft 設定為識別提供者,因此租使用者標識碼和其他數個必要值已經在 App Service 應用程式設定中。

下列程式代碼已在範例應用程式中為您提供。 您需要瞭解其運作原因及其運作方式,以便您將這項工作套用至您建置的其他需要相同功能的應用程式。

檢查程式碼以取得租戶 ID

  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 環境變數取得目前的租用戶標識碼。 可以使用正則表達式從變數中解析出識別碼。

使用 MSAL.js 查看程式碼以取得 Graph 憑證

  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。
  • 授與系統管理員同意,以略過後端應用程式的使用者同意畫面。
  • 變更應用程式程式代碼,將從前端應用程式傳送的存取令牌轉換為具有下游服務所需許可權的存取令牌,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. 在瀏覽器中使用前端網站。 如果令牌已過期,您可能需要更新令牌。

  2. 選取 Get user's profile。 這會將您持有人權杖中的驗證傳遞至後端。

  3. 後端回傳您帳戶的 Microsoft Graph 實際概況。

    Web 瀏覽器的螢幕快照,顯示前端應用程式在從後端應用取得真實使用者資料後的狀態。

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表示後端 App Service 未獲授權傳回 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 服務?

本教學課程示範向 Microsoft Graph 驗證的 API 應用程式,不過,可以套用相同的一般步驟來代表使用者存取任何 Azure 服務。

  1. 前端應用程式沒有變更。 只會變更後端的驗證應用程式註冊和後端應用程式原始程式碼。
  2. 將使用者的後端 API 範圍令牌交換成用於存取您想要的下游服務的令牌。
  3. 在下游服務的 SDK 中使用令牌來建立用戶端。
  4. 使用下游用戶端來存取服務功能。

後續步驟