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

本文示範一個 Java Spring Boot Web 應用程式,說明如何讓使用者登入,並取得用來呼叫 Microsoft Graph 的存取權杖。 它會使用 適用於 Java 的 Microsoft Entra ID Spring Boot Starter 用戶端程式庫 來進行驗證、授權和權杖取得。 它使用 Microsoft Graph SDK for Java 從 Graph 取得資料。

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

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

應用程式會使用適用於 Java 的 Microsoft Entra ID Spring Boot Starter 用戶端程式庫,從 Microsoft Entra ID 取得供 Microsoft Graph 使用的 存取權杖。 存取令牌證明用戶有權存取範圍中所定義的 Microsoft 圖形 API 端點。

必要條件

  • JDK 15 版。 此範例是在 Java 15 的系統上開發,但可能與其他版本相容。
  • Maven 3
  • 建議使用 適用於 Visual Studio Code 的 Java 擴充功能套件,在 Visual Studio Code 中執行此範例。
  • Microsoft Entra ID 租用戶。 如需更多資訊,請參閱 如何取得 Microsoft Entra ID 租用戶。
  • 您Microsoft Entra ID 租使用者中的用戶帳戶。 此範例不適用於個人Microsoft帳戶。 因此,如果您使用個人帳戶登入 Azure 入口網站,而且您的目錄中沒有使用者帳戶,您現在需要立即建立一個。
  • Visual Studio Code
  • 適用於 Visual Studio Code 的 Azure 工具

建議

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

設定範例

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

複製或下載範例存放庫

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

git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 4-spring-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-spring-webapp-call-graph)

若要註冊應用程式,請使用下列步驟:

  1. 前往Azure 入口網站,然後選取Microsoft Entra ID。

  2. 在瀏覽窗格中選取 [應用程式註冊 ],然後選取 [ 新增註冊]。

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

    • 在 名稱 區段中,輸入有意義的應用程式名稱,以顯示給應用程式使用者,例如 。
    • 在 [支援的帳戶類型] 底下,選取 [僅在此組織目錄中的帳戶]。
    • 在 重新導向 URI (選用) 區段中,於下拉式方塊中選取 Web,然後輸入下列重新導向 URI:。
  4. 選取 註冊 以建立應用程式。

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

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

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

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

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

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

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

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

  13. 選取 新增權限,然後確認已選取 Microsoft API 索引標籤。

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

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

  16. 選取 新增權限。


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

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

注意

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

  1. 在 IDE 中開啟專案。

  2. 開啟 src\main\resources\application.yml 檔案。

  3. 找出預留位置 ,並將現有的值替換為您的 Microsoft Entra 租用戶識別碼。

  4. 找出預留位置 ,並以從 Azure 入口網站複製的 應用程式應用程式 ID 或 取代現有值。

  5. 找出預留位置 ,然後將現有的值替換為您在建立 時從 Azure 入口網站複製並儲存的值。

執行範例

  • 部署至 Azure 容器應用程式
  • 在本機執行

下列各節說明如何將範例部署至 Azure 容器應用程式。

必要條件

  • Azure 帳戶。 如果您還沒有帳戶,請建立免費帳戶。 您需要 Azure 訂用帳戶的 Contributor 或 Owner 許可權,才能繼續進行。 如需更多資訊,請參閱 使用 Azure 入口網站指派 Azure 角色。
  • Azure CLI。
  • Azure 容器應用程式 CLI 擴充功能,版本為 或更新版本。 若要安裝最新版本,請使用 命令。
  • Java Development Kit 17 或更新版本。
  • Maven.

準備 Spring 專案

使用下列步驟來準備專案:

  1. 使用下列 Maven 命令來建置專案:

    mvn clean verify
    
  2. 使用下列命令在本機執行範例專案:

    mvn spring-boot:run
    

設定

若要從 CLI 登入 Azure,請執行下列命令並遵循提示來完成驗證流程。

az login

若要確定您執行的是最新版本 CLI,請執行升級命令。

az upgrade

接下來,安裝或更新 CLI 的 Azure 容器應用程式延伸模組。

如果您在 Azure CLI 中執行 命令時收到缺少參數的錯誤,請確定您已安裝最新版的 Azure 容器應用程式 擴充功能。

az extension add --name containerapp --upgrade

注意

從 2024 年 5 月開始,Azure CLI 延伸模組預設不會再啟用預覽功能。 若要存取 Container Apps 的預覽功能,請使用安裝 Container Apps 擴充功能。

az extension add --name containerapp --upgrade --allow-preview true

現在已安裝目前的擴充功能或模組,請註冊 和 命名空間。

注意

Azure 容器應用程式資源已從 命名空間移轉到 命名空間。 如需詳細資訊,請參閱 2022 年 3 月從 Microsoft.Web 移轉至 Microsoft.App 的命名空間移轉。

az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights

建立 Azure 容器應用程式 環境

現在您的 Azure CLI 設定已完成,接下來您可以定義本文中使用的環境變數了。

在您的 bash shell 中定義下列變數。

export RESOURCE_GROUP="ms-identity-containerapps"
export LOCATION="canadacentral"
export ENVIRONMENT="env-ms-identity-containerapps"
export API_NAME="ms-identity-api"
export JAR_FILE_PATH_AND_NAME="./target/ms-identity-spring-boot-webapp-0.0.1-SNAPSHOT.jar"

建立資源群組。

az group create  \
    --name $RESOURCE_GROUP \
    --location $LOCATION \

使用自動產生的Log Analytics工作區建立環境。

az containerapp env create \
    --name $ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION

顯示容器應用程式環境的預設網域。 記下此網域以供稍後章節使用。

az containerapp env show \
    --name $ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --query properties.defaultDomain

準備應用程式以進行部署

當您將應用程式部署至 Azure 容器應用程式 時,您的重新導向 URL 會變更為 Azure 容器應用程式 中已部署應用程式實例的重新導向 URL。 按照下列步驟,在您的 application.yml 檔案中變更這些設定:

  1. 前往應用程式的 src\main\resources\application.yml 檔案,並將 的值變更為已部署應用程式的網域名稱,如下列範例所示。 請務必將 和 替換為您的實際值。 例如,若使用上一個步驟中 Azure Container Apps 環境的預設網域,並以 作為您的應用程式名稱,則您會使用 作為 的值。

    post-logout-redirect-uri: https://<API_NAME>.<default-domain-of-container-app-environment>
    
  2. 儲存此檔案之後,請使用下列命令重建您的應用程式:

    mvn clean package
    

重要

應用程式的 application.yml 檔案目前在 參數中儲存了您的用戶端密鑰值。 將此值保留在這個檔案中並不好的做法。 如果您將檔案提交到 Git 儲存庫,也可能會承擔風險。 如需了解建議的做法,請參閱 在 Azure 容器應用程式 中管理祕密。

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

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

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

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

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

  4. 從選單中選擇 驗證。

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

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

  7. 選取 儲存。

部署應用程式

將 JAR 套件部署至 AAzure 容器應用程式。

注意

如有必要,您可以在 Java 建置環境變數中指定 JDK 版本。 如需詳細資訊,請參閱 Azure 容器應用程式 中適用於 Java 的建置環境變數。

現在您可以使用 CLI 命令部署 WAR 檔案。

az containerapp up \
    --name $API_NAME \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION \
    --environment $ENVIRONMENT \
    --artifact <JAR_FILE_PATH_AND_NAME> \
    --ingress external \
    --target-port 8080 \
    --query properties.configuration.ingress.fqdn

注意

預設的 JDK 版本為 17。 如果您需要變更 JDK 版本以便與您的應用程式相容,可以使用 參數來調整版本號碼。

如需其他建置環境變數,請參閱 Azure 容器應用程式 中適用於 Java 的建置環境變數。

驗證應用程式

在此範例中, 命令包含 引數,該引數會傳回完整網域名稱 (FQDN),也稱為應用程式的 URL。 使用下列步驟來檢查應用程式的記錄,以調查任何部署問題:

  1. 在 部署 區段的 輸出 頁面中取得輸出應用程式 URL。

  2. 從 Azure 容器應用程式 執行個體 概觀 頁面的導覽窗格中,選取 記錄 以查看應用程式記錄。

探索範例

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

  1. 請注意畫面中央顯示的已登入或註銷狀態。
  2. 選取角落中的上下文相關按鈕。 當您第一次執行應用程式時,此按鈕會顯示為登入。 或者,選取 權杖詳細資料 或 呼叫圖。 由於此頁面受到保護且需要驗證,因此會自動重新導向至登入頁面。
  3. 在下一個頁面上,遵循指示,並使用 Microsoft Entra ID 租使用者中的帳戶登入。
  4. 在同意畫面上,請注意所要求的範圍。
  5. 順利完成登入流程時,您應該重新導向至首頁 ,其中顯示 登入狀態 ,或另一個頁面,視觸發登入流程的按鈕而定。
  6. 請注意,上下文相關按鈕現在會顯示 [註銷 ] 並顯示您的用戶名稱。
  7. 如果您位於首頁,請選取 ID 權杖詳細資料,以查看 ID 權杖中部分經解碼的宣告內容。
  8. 選取 呼叫 Graph,以呼叫 Microsoft Graph 的 /me 端點,並查看所取得的部分使用者詳細資料。
  9. 使用角落的按鈕登出。狀態頁面會反映新的狀態。

關於程式碼

此範例示範如何使用 適用於 Java 的 Microsoft Entra ID Spring Boot Starter 用戶端程式庫,讓使用者登入您的 Microsoft Entra ID 租用戶,並取得可用來呼叫 Microsoft Graph 的存取權杖。 此範例也使用了 Spring OAuth2 客戶端和 Spring Web Boot 啟動器。

目錄

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

檔案/資料夾 描述
pom.xml 應用程式相依性。
src/main/resources/templates/ 適用於 UI 的 Thymeleaf 範本。
src/main/resources/application.yml 應用程式與 Microsoft Entra ID 啟動程式庫組態。
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ 此目錄包含主要應用程式進入點、控制器和設定類別。
.../MsIdentitySpringBootWebappApplication.java 主要類別。
.../SampleController.java 具有端點映射的控制器
.../SecurityConfig.java 安全性設定 - 例如,需要驗證的路由。
.../Utilities.java 公用程式類別 - 例如篩選識別碼令牌宣告。
CHANGELOG.md 範例的變更清單。
CONTRIBUTING.md 參與範例的指導方針。
許可證 範例的授權條款。

標識元令牌宣告

為了擷取權杖詳細資料,應用程式會如以下範例所示,在請求對應中使用 Spring Security 的 和 物件。 如需了解此應用程式如何使用 ID 權杖宣告的完整詳細資訊,請參閱 範例控制器。

import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
//...
@GetMapping(path = "/some_path")
public String tokenDetails(@AuthenticationPrincipal OidcUser principal) {
    Map<String, Object> claims = principal.getIdToken().getClaims();
}

針對登入,應用程式會向 Microsoft Entra ID Spring Boot Starter 用戶端連結庫 for Java 自動設定Microsoft Entra ID 登入端點提出要求,如下列範例所示:

<a class="btn btn-success" href="/oauth2/authorization/azure">Sign In</a>

若要登出,應用程式會向 端點傳送 POST 要求,如以下範例所示:

<form action="#" th:action="@{/logout}" method="post">
  <input class="btn btn-warning" type="submit" value="Sign Out" />
</form>

依驗證狀態而定的 UI 元素

應用程式在UI範本頁面中有一些簡單的邏輯,可用來根據使用者是否已驗證來判斷要顯示的內容,如下列使用 Spring Security Thymeleaf 標籤的範例所示:

<div sec:authorize="isAuthenticated()">
  this content only shows to authenticated users
</div>
<div sec:authorize="isAnonymous()">
  this content only shows to not-authenticated users
</div>

使用 AADWebSecurityConfigurerAdapter 保護路由

預設情況下,應用程式會保護 ID Token Details 和 Call Graph 頁面,讓只有已登入的使用者才能存取這些頁面。 應用程式會根據 application.yml 檔案中的 屬性設定這些路由。 若要設定應用程式的特定需求,您可以在您的其中一個類別中擴充 。 例如,請參閱此應用程式的 SecurityConfig 類別,如下列程式碼所示:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends AADWebSecurityConfigurerAdapter{
  @Value( "${app.protect.authenticated}" )
  private String[] protectedRoutes;

    @Override
    public void configure(HttpSecurity http) throws Exception {
    // use required configuration form AADWebSecurityAdapter.configure:
    super.configure(http);
    // add custom configuration:
    http.authorizeRequests()
      .antMatchers(protectedRoutes).authenticated()     // limit these pages to authenticated users (default: /token_details, /call_graph)
      .antMatchers("/**").permitAll();                  // allow all other routes.
    }
}

呼叫圖表

當使用者瀏覽至 時,應用程式會使用 Microsoft Entra ID boot starter 所準備的 或 ,建立 的執行個體。 應用程式會要求 呼叫 端點,並顯示目前已登入使用者的詳細資料。 來自 適用於 Java 的 Microsoft Graph SDK,第 3 版。

必須準備好正確的權限範圍。 請參閱 application.yml 檔案和下列的 範圍 一節。 用於取得存取權杖,並將其放入 請求的 標頭中,如下列範例所示:

//see SampleController.java
@GetMapping(path = "/call_graph")
public String callGraph(@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graphAuthorizedClient) {
  // See the Utilities.graphUserProperties() method for the full example of the following operation:
  GraphServiceClient graphServiceClient = Utilities.getGraphServiceClient(graphAuthorizedClient);
  User user = graphServiceClient.me().buildRequest().get();
  return user.displayName;
}

下列來自 application.yml 檔案的 範例會顯示所要求的範圍:

# see application.yml file
authorization-clients:
  graph:
    # Specifies the Microsoft Graph scopes that your app needs access to:
    scopes: https://graph.microsoft.com/User.Read

範圍

範圍會告知 Microsoft Entra ID 應用程式所要求的存取層級。 如需此應用程式所要求的Microsoft Graph 範圍,請參閱 application.yml。

預設情況下,應用程式會將 scopes 值設為 。 範圍用於從 /me 端點 存取目前已登入使用者的資訊。 對 /me 端點 的有效請求必須包含 範圍。

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

在此應用程式中, 會顯示可證明使用者已同意哪些範圍的存取權杖。 應用程式會使用此權杖來建立 的執行個體,用來處理 Graph 要求。

使用 ,會建立要求並將其傳送至 。 存取令牌會放在請求的 標頭中。

其他相關資訊

  • Microsoft 身分識別平台文件
  • Microsoft 驗證程式庫 (MSAL) 概觀
  • 快速入門:在 Microsoft 身分識別平台中註冊應用程式
  • 快速入門:設定用戶端應用程式以存取 Web API
  • 瞭解 Microsoft Entra ID 應用程式同意體驗
  • 瞭解使用者和系統管理員同意
  • Microsoft Entra ID 中的應用程式與服務主體物件
  • 國家雲
  • MSAL 程式碼範例
  • 適用於 Java 的 Azure Active Directory Spring Boot Starter 用戶端程式庫
  • 適用於 Java 的 Microsoft 驗證程式庫 (MSAL4J)
  • MSAL4J 維基
  • ID 權杖
  • Microsoft 身分識別平台中的存取權杖

如需了解 OAuth 2.0 通訊協定如何在此案例及其他案例中運作的詳細資訊,請參閱 Microsoft Entra ID 的驗證案例。