啟用 Java Tomcat 應用程式以登入使用者並存取 Microsoft Graph

本文示範一個 Java Tomcat 應用程式,說明如何讓使用者登入並取得用於呼叫 Microsoft Graph 的存取權杖。 它使用 適用於 Java 的 Microsoft 驗證程式庫 (MSAL)。

下圖顯示應用程式的拓撲:

顯示應用程式拓撲的圖表。

用戶端應用程式使用 MSAL for Java (MSAL4J) 讓使用者登入,並從 Microsoft Entra ID 取得供 Microsoft Graph 使用的 存取權杖。 存取令牌證明用戶有權存取範圍中所定義的 Microsoft 圖形 API 端點。

必要條件

  • Java 8 或更高版本
  • Maven 3
  • Microsoft Entra ID 租用戶。 如需更多資訊,請參閱 如何取得 Microsoft Entra ID 租用戶。
  • 如果您只想使用組織目錄中的帳戶,也就是以單一租用戶模式運作,則請使用您自己的 Microsoft Entra ID 租用戶中的使用者帳戶。 如果您尚未在您的租用戶中建立使用者帳戶,請先建立帳戶,再繼續操作。 如需更多資訊,請參閱 如何建立、邀請和刪除使用者。
  • 如果您想要使用任何組織目錄中的帳戶(也就是在多租用戶模式下),則需要有任何組織的 Microsoft Entra ID 租用戶中的使用者帳戶。 此範例必須修改,才能搭配個人 Microsoft 帳戶使用。 如果您尚未在您的租用戶中建立使用者帳戶,請先建立帳戶,再繼續操作。 如需更多資訊,請參閱 如何建立、邀請和刪除使用者。
  • 如果您想要使用個人 Microsoft 帳戶,則需使用個人 Microsoft 帳戶(例如 Xbox、Hotmail、Live 等)。
  • Tomcat 9
  • Visual Studio Code
  • 適用於 Visual Studio Code 的 Azure 工具

建議

  • 對 Java / Jakarta Servlets 有一些基本了解。
  • 對 Linux/OSX 終端機操作有基本了解。
  • jwt.ms 用於檢查您的權杖。
  • Fiddler 用於監控您的網路活動及進行疑難排解。
  • 關注 Microsoft Entra 部落格,隨時掌握最新發展。

設定範例

下列各節說明如何設定範例應用程式。

複製或下載範例存放庫

若要複製範例,請開啟Bash視窗,並使用下列命令:

git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 3-java-servlet-web-app/2-Authorization-I/call-graph

或者,瀏覽至 ms-identity-msal-java-samples 存放庫,然後將其下載為 .zip 檔案,並解壓縮到您的硬碟。

重要

若要避免 Windows 上的檔案路徑長度限制,請將存放庫複製到硬碟根目錄附近的目錄中。

在 Microsoft Entra ID 租用戶中註冊範例應用程式

此範例中有一個專案。 下列各節說明如何使用 Azure 入口網站 註冊應用程式。

選擇您要在其中建立應用程式的 Microsoft Entra ID 租用戶

若要選擇您的租使用者,請使用下列步驟:

  1. 登入 Azure 入口網站。

  2. 如果您的帳戶存在於一個以上的 Microsoft Entra ID 租用戶中,請在 Azure 入口網站右上角選取您的個人檔案,然後選取 切換目錄,將您的工作階段切換至所需的 Microsoft Entra ID 租用戶。

註冊應用程式(java-servlet-webapp-call-graph)

首先,請依照 快速入門:使用 Microsoft 身分識別平台註冊應用程式 中的指示,在 Azure 入口網站 中註冊新應用程式。

然後,使用下列步驟來完成註冊:

  1. 前往適用於開發人員的 Microsoft 身分識別平台應用程式註冊頁面。

  2. 選取 新增註冊。

  3. 在出現的 [ 註冊應用程式] 頁面中 ,輸入下列應用程式註冊資訊:

    • 在 Name 區段中,輸入一個具意義的應用程式名稱,供應用程式使用者顯示,例如:。

    • 在 [支持的帳戶類型] 底下,選取下列其中一個選項:

      • 如果您正在建置的應用程式僅供您租用戶中的使用者使用,請選取 僅此組織目錄中的帳戶;也就是說,這是 單一租用戶 應用程式。
      • 如果您希望任何 Microsoft Entra ID 租用戶中的使用者都能使用您的應用程式,請選取任何組織目錄中的帳戶,也就是說,這是多租用戶應用程式。
      • 選取 任何組織目錄中的帳戶和 Microsoft 個人帳戶,以涵蓋最廣泛的客戶群,也就是同時支援 Microsoft 個人帳戶的多租用戶應用程式。
    • 選取 [個人Microsoft帳戶],僅供個人Microsoft帳戶 的使用者使用 -- 例如 Hotmail、Live、Skype 和 Xbox 帳戶。

    • 在 重新導向 URI 區段中,於下拉式方塊選取 Web,然後輸入下列重新導向 URI:。

  4. 選取 註冊 以建立應用程式。

  5. 在應用程式的註冊頁面上,尋找並複製 應用程式 (用戶端) 識別碼 值,以供稍後使用。 您會在應用程式的組態檔或檔案中使用此值。

  6. 選取儲存以儲存變更。

  7. 在應用程式的註冊頁面上,選取 瀏覽窗格中的 [憑證和秘密 ],以開啟您可以產生秘密並上傳憑證的頁面。

  8. 在用戶端密碼區段底下,選取新增用戶端密碼。

  9. 輸入描述 - 例如, 應用程式秘密。

  10. 選取祕密的到期日,或指定自訂存留期。 用戶端機密的有效期限限制為 24 個月,Microsoft 建議有效期少於 12 個月。 對於生產應用程式,建議使用憑證或聯邦身份憑證,而非用戶端秘密。

  11. 選取新增。 產生的值隨即顯示。

  12. 複製並儲存產生的值,以供後續步驟使用。 您需要此值用於您的程式碼設定檔。 此值不會再次顯示,而且您無法透過任何其他方式加以擷取。 因此,請務必先在 Azure 入口網站中將其儲存,再切換到任何其他畫面或窗格。

  13. 在應用程式的註冊頁面上,從瀏覽窗格中選取 [API 許可權 ],以開啟頁面,以新增對應用程式所需 API 的存取權。

  14. 選取 新增權限。

  15. 確認已選取 Microsoft APIs 索引標籤頁。

  16. 在 [常用的 Microsoft API] 區段中,選取 [Microsoft Graph]。

  17. 在 [ 委派的許可權] 區段中,從清單中選取 [User.Read ]。 如有需要請使用搜尋方塊。

  18. 選取 新增權限。


設定應用程式 (java-servlet-webapp-call-graph) 以使用您的應用程式註冊資訊

使用下列步驟來設定應用程式:

注意

在以下步驟中, 與 或 相同。

  1. 在 IDE 中開啟專案。

  2. 開啟 ./src/main/resources/authentication.properties 檔案。

  3. 找出字串 。 以以下其中一個值取代現有值:

    • 如果您是以 僅限此組織目錄中的帳戶 選項註冊您的應用程式,則為您的 Microsoft Entra ID 租用戶識別碼。
    • 如果您使用 任何組織目錄中的帳戶 選項註冊您的應用程式,則該字為 。
    • 如果您使用 任何組織目錄中的帳戶和個人 Microsoft 帳戶 選項註冊您的應用程式,則會顯示字詞 。
    • 如果您使用個人 Microsoft 帳戶選項註冊應用程式,則該字詞為。
  4. 尋找字串 ,並將現有的值取代為從 Azure 入口網站複製的 應用程式的應用程式識別碼或 。

  5. 尋找字串 ,並將現有的值替換為您在 Azure 入口網站中建立 應用程式時所儲存的值。

建置範例

若要使用 Maven 建置範例,請流覽至包含 範例pom.xml 檔案的目錄,然後執行下列命令:

mvn clean package

此命令會產生 您可以在各種應用程式伺服器上執行的 .war 檔案。

執行範例

  • 部署到 Azure App 服務
  • 在本機執行

下列各節說明如何將範例部署至 Azure App 服務。

必要條件

  • 適用於 Azure App 服務 應用程式的 Maven 外掛程式

    如果 Maven 不是您慣用的開發工具,請參閱下列使用其他工具的類似教學課程:

    • IntelliJ IDEA
    • Eclipse
    • Visual Studio Code

設定 Maven 外掛程式

當您部署至 Azure App 服務 時,部署會自動使用 Azure CLI 中的 Azure 認證。 如果 Azure CLI 未安裝在本機,則 Maven 外掛程式會使用 OAuth 或裝置登入進行驗證。 如需更多資訊,請參閱使用 Maven 外掛程式進行驗證。

使用下列步驟來設定外掛程式:

  1. 執行下列命令來設定部署。 此命令可協助您設定 Azure App 服務 操作系統、Java 版本和 Tomcat 版本。

    mvn com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:config
    
  2. 若要建立新的執行組態,請按Y,然後按Enter。

  3. 對於 定義 OS 的值,Windows 請按 1,Linux 請按 2,然後按 Enter。

  4. 在 為 javaVersion 定義值 中,按 2 以選擇 Java 11,然後按 Enter。

  5. 在 定義 webContainer 的值 中,按下 4 以選擇 Tomcat 9.0,然後按下 Enter。

  6. 針對 定義 pricingTier 的值,按 Enter 以選取預設的 P1v2 層級。

  7. 若要確認,請按Y,然後按Enter。

下列範例顯示部署程式的輸出:

Please confirm webapp properties
AppName : msal4j-servlet-auth-1707209552268
ResourceGroup : msal4j-servlet-auth-1707209552268-rg
Region : centralus
PricingTier : P1v2
OS : Linux
Java Version: Java 11
Web server stack: Tomcat 9.0
Deploy to slot : false
Confirm (Y/N) [Y]: [INFO] Saving configuration to pom.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  37.112 s
[INFO] Finished at: 2024-02-06T08:53:02Z
[INFO] ------------------------------------------------------------------------

確認您的選擇之後,外掛程式會將必要的外掛程式元素和設定新增至專案的pom.xml檔案,以將您的應用程式設定為在 Azure App 服務 中執行。

pom.xml檔案的相關部分看起來應該類似下列範例:

<build>
    <plugins>
        <plugin>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>>azure-webapp-maven-plugin</artifactId>
            <version>x.xx.x</version>
            <configuration>
                <schemaVersion>v2</schemaVersion>
                <resourceGroup>your-resourcegroup-name</resourceGroup>
                <appName>your-app-name</appName>
            ...
            </configuration>
        </plugin>
    </plugins>
</build>

您可以直接在pom.xml中修改 App Service 的設定。 下表列出一些常見的設定:

屬性 必填 描述
subscriptionId false 訂用帳戶標識碼。
resourceGroup true 應用程式的 Azure 資源群組。
appName true 應用程式的名稱。
region false 裝載您應用程式的區域。 預設值是 。 如需了解可用區域,請參閱 支援的區域。
pricingTier false 應用程式的定價層。 對於生產工作負載,預設值為 。 Java 開發和測試的建議最小值為 。 如需更多資訊,請參閱 App Service 定價。
runtime false 執行時間環境設定。 如需更多資訊,請參閱 組態詳細資料。
deployment false 部署設定。 如需更多資訊,請參閱 組態詳細資料。

如需設定的完整清單,請參閱外掛程式參考文件。 所有 Azure Maven 外掛程式都會共用一組常見的組態。 如需了解這些組態,請參閱 常見組態。 如需 Azure App 服務 專屬的設定,請參閱Azure 應用程式:設定詳細資料。

請務必先將 和 的值另行保存,以供後續使用。

準備應用程式以進行部署

當您將應用程式部署至 App Service 時,重新導向 URL 會變更為已部署應用程式實例的重新導向 URL。 使用下列步驟來變更屬性檔案中的這些設定:

  1. 瀏覽至您應用程式的 authentication.properties 檔案,並將 的值變更為已部署應用程式的網域名稱,如下列範例所示。 例如,如果您在上一個步驟中為應用程式名稱選擇了 ,現在就必須使用 作為 的值。 請確定您也已將通訊協定從 變更為 。

    # app.homePage is by default set to dev server address and app context path on the server
    # for apps deployed to azure, use https://your-sub-domain.azurewebsites.net
    app.homePage=https://<your-app-name>.azurewebsites.net
    
  2. 儲存此檔案之後,請使用下列命令重建您的應用程式:

    mvn clean package
    

重要

在同一個 authentication.properties 檔案中,您有一個用於 的設定。 將此值部署至 App Service 不是很好的做法。 在程序代碼中保留此值並可能將其推送至 Git 存放庫,這兩者都不是很好的做法。 如需從程式碼中移除此祕密值,您可以在 部署至 App Service - 移除祕密值 一節中找到更詳細的指引。 本指南新增了額外步驟,用於將祕密值推送至 金鑰保存庫,並使用 金鑰保存庫參考。

更新您的 Microsoft Entra ID 應用程式註冊

由於重新導向 URI 會變更為您部署至 Azure App 服務 的應用程式 URI,因此您也需要在 Microsoft Entra ID 應用程式註冊中變更重新導向 URI。 請使用下列步驟來進行此變更:

  1. 前往適用於開發人員的 Microsoft 身分識別平台應用程式註冊頁面。

  2. 使用搜尋方塊搜尋您的應用程式註冊,例如 。

  3. 選取應用程式名稱以開啟您的應用程式註冊。

  4. 從選單中選擇 驗證。

  5. 在 Web重新導向 URI 區段中,選取 新增 URI。

  6. 填入您應用程式的 URI,並加上 ,例如 。

  7. 選取 儲存。

部署應用程式

您現在已準備好將應用程式部署至 Azure App 服務。 使用下列命令,確定您已登入 Azure 環境以執行部署:

az login

在pom.xml檔案中備妥所有組態後,您現在可以使用下列命令將 Java 應用程式部署至 Azure:

mvn package azure-webapp:deploy

部署完成後,您的應用程式已可於 使用。 使用本機網頁瀏覽器開啟 URL,您應該會看到 應用程式的起始頁面。

探索範例

使用下列步驟來探索範例:

  1. 請注意畫面中央顯示的已登入或註銷狀態。
  2. 選取角落中的上下文相關按鈕。 當您第一次執行應用程式時,此按鈕會顯示為登入。
  3. 在下一個頁面上,遵循指示,並使用 Microsoft Entra ID 租使用者中的帳戶登入。
  4. 在同意畫面上,請注意所要求的範圍。
  5. 請注意,上下文相關按鈕現在會顯示 [註銷 ] 並顯示您的用戶名稱。
  6. 選取ID 權杖詳細資料即可查看 ID 權杖部分已解碼的宣告。
  7. 選取 呼叫 Graph,對 Microsoft Graph 的 /me 端點 發出呼叫,並查看所取得的部分使用者詳細資料。
  8. 使用角落的按鈕登出。

關於程式碼

此範例會使用 MSAL for Java (MSAL4J) 來登入使用者,並取得 Microsoft 圖形 API 的令牌。 它使用 Microsoft Graph SDK for Java 從 Graph 取得資料。 您必須使用 Maven 將這些連結庫新增至您的專案。

如果您想要重現此範例的行為,可以複製 pom.xml 檔案,以及 src/main/java/com/microsoft/azuresamples/msal4j 資料夾中的 helpers 和 authservlets 資料夾內容。 您也需要 authentication.properties 檔案。 這些類別和檔案包含一般程式代碼,您可以在各種應用程式中使用。 您也可以複製範例的其餘部分,但會特別建置其他類別和檔案,以解決此範例的目標。

目錄

下表顯示範例項目資料夾的內容:

檔案/資料夾 描述
src/main/java/com/microsoft/azuresamples/msal4j/callgraphwebapp/ 此目錄包含定義應用程式後端商業規則的類別。
src/main/java/com/microsoft/azuresamples/msal4j/authservlets/ 此目錄包含用於登入和註銷端點的類別。
*Servlet.java 所有可用的端點都定義在 Java 類別中,名稱結尾為 Servlet。
src/main/java/com/microsoft/azuresamples/msal4j/helpers/ 用於身分驗證的輔助類別。
AuthenticationFilter.java 將對受保護端點的未經驗證請求重新導向至 401 頁面。
src/main/resources/authentication.properties Microsoft Entra 識別碼和程序設定。
src/main/webapp/ 此目錄包含 UI - JSP 範本
CHANGELOG.md 範例的變更清單。
CONTRIBUTING.md 參與範例的指導方針。
許可證 範例的授權條款。

ConfidentialClientApplication

系統會在 AuthHelper.java 檔案中建立 執行個體,如下列範例所示。 此物件可協助建立 Microsoft Entra ID 授權 URL,並協助將驗證權杖交換為存取權杖。

// getConfidentialClientInstance method
IClientSecret secret = ClientCredentialFactory.createFromSecret(SECRET);
confClientInstance = ConfidentialClientApplication
                     .builder(CLIENT_ID, secret)
                     .authority(AUTHORITY)
                     .build();

下列參數用於具現化:

  • 應用程式的用戶端識別碼。
  • 客戶端密碼,這是機密用戶端應用程式的需求。
  • Microsoft Entra ID 授權單位,其中包含您的 Microsoft Entra 租用戶 ID。

在此範例中,這些值會使用 Config.java 檔案中的屬性讀取器,從 authentication.properties 檔案中讀取。

逐步解說

下列步驟提供應用程式的功能的逐步解說:

  1. 登入程序的第一個步驟,是向您 Microsoft Entra ID 租用戶上的 端點傳送要求。 MSAL4J 實例用於建構授權請求 URL。 應用程式會將瀏覽器重新導向至此 URL,也就是使用者登入的位置。

    final ConfidentialClientApplication client = getConfidentialClientInstance();
    AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters.builder(Config.REDIRECT_URI, Collections.singleton(Config.SCOPES))
            .responseMode(ResponseMode.QUERY).prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build();
    
    final String authorizeUrl = client.getAuthorizationRequestUrl(parameters).toString();
    contextAdapter.redirectUser(authorizeUrl);
    

    下列清單描述此程式碼的功能:

    • :為了建置 而必須設定的參數。
    • :Microsoft Entra ID 在收集使用者認證後,將瀏覽器連同授權碼重新導向到的位置。 它必須與 Azure portal 中 Microsoft Entra ID 應用程式註冊內的重新導向 URI 相符
    • :範圍是應用程式要求的權限。
      • 一般而言,三個範圍 即足以接收 ID 權杖回應。
      • 您可以在 authentication.properties 檔案中找到應用程式所要求的完整範圍清單。 您可以新增更多範圍,例如 。
  2. 使用者會看到 Microsoft Entra ID 發出的登入提示。 如果登入嘗試成功,則會將使用者的瀏覽器重新導向至應用程式的重新導向端點。 對此端點的有效請求包含授權碼。

  3. 接著, 執行個體會使用此授權碼,向 Microsoft Entra ID 換取 ID 權杖和存取權杖。

    // First, validate the state, then parse any error codes in response, then extract the authCode. Then:
    // build the auth code params:
    final AuthorizationCodeParameters authParams = AuthorizationCodeParameters
            .builder(authCode, new URI(Config.REDIRECT_URI)).scopes(Collections.singleton(Config.SCOPES)).build();
    
    // Get a client instance and leverage it to acquire the token:
    final ConfidentialClientApplication client = AuthHelper.getConfidentialClientInstance();
    final IAuthenticationResult result = client.acquireToken(authParams).get();
    

    下列清單描述此程式碼的功能:

    • :為了將授權碼交換為 ID 權杖和/或存取權杖而必須設定的參數。
    • :重新導向端點所接收的授權碼。
    • :必須再次傳入上一步中使用的重新導向 URI。
    • :必須再次傳入前一步驟中使用的範圍。
  4. 如果 成功,則會擷取權杖宣告。 如果 nonce 檢查通過,結果會放入 (即 的一個執行個體)中,並儲存至工作階段。 然後,應用程式可以在每當需要存取它時,透過 的執行個體從工作階段中建立 的執行個體,如下列程式碼所示:

    // parse IdToken claims from the IAuthenticationResult:
    // (the next step - validateNonce - requires parsed claims)
    context.setIdTokenClaims(result.idToken());
    
    // if nonce is invalid, stop immediately! this could be a token replay!
    // if validation fails, throws exception and cancels auth:
    validateNonce(context);
    
    // set user to authenticated:
    context.setAuthResult(result, client.tokenCache().serialize());
    

保護路由

如需範例應用程式如何篩選路由存取的資訊,請參閱 AuthenticationFilter.java。 在 authentication.properties 檔案中, 屬性包含以逗號分隔的路由,只有已驗證的使用者可以存取這些路由,如下列範例所示:

# for example, /token_details requires any user to be signed in and does not require special roles or groups claim(s)
app.protect.authenticated=/token_details, /call_graph

呼叫圖表

當使用者瀏覽至 時,應用程式會建立 的執行個體(來自 Java Graph SDK),並傳入已登入使用者的存取權杖。 Graph 用戶端會將存取權杖放在其要求的 標頭中。 然後,應用程式會要求 Graph 用戶端呼叫 端點,以取得目前登入的使用者詳細資料。

如果您已經有適用於 Graph 服務 `` 範圍的有效存取權杖,則只需要下列程式碼即可存取 `` 端點:

//CallGraphServlet.java
User user = GraphHelper.getGraphClient(contextAdapter).me().buildRequest().get();

範圍

範圍會告知 Microsoft Entra ID 應用程式所要求的存取權層級。

根據要求的範圍,Microsoft Entra ID 會在登入時向用戶顯示同意對話。 如果使用者同意一個或多個範圍並取得權杖,則已同意的範圍會編碼到產生的 中。

如需應用程式要求的範圍,請參閱 authentication.properties。 預設情況下,應用程式會將 scopes 值設為 。 此特定Microsoft 圖形 API 範圍是存取目前登入用戶的資訊。 用來存取此資訊的 Graph 端點是 。 任何對此端點提出的有效請求,都必須在 標頭中攜帶包含 範圍的 。

其他相關資訊

  • 適用於 Java 的 Microsoft 驗證程式庫 (MSAL)
  • Microsoft 身分識別平台(適用於開發人員的 Microsoft Entra ID)
  • 快速入門:在 Microsoft 身分識別平台中註冊應用程式
  • 瞭解 Microsoft Entra ID 應用程式同意體驗
  • 瞭解使用者和系統管理員同意
  • MSAL 程式碼範例