使用群組和群組宣告來保護 Java Tomcat 應用程式

本文說明如何建立 Java Tomcat 應用程式,以使用 適用於 Java 的 Microsoft 驗證程式庫 (MSAL) 讓使用者登入。 應用程式也會根據Microsoft Entra ID 安全組成員資格來限制對頁面的存取。

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

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

用戶端應用程式使用 MSAL for Java (MSAL4J) 讓使用者登入 Microsoft Entra ID 租用戶,並從 Microsoft Entra ID 取得 ID 權杖。 ID 權杖可證明使用者已透過此租用戶完成驗證。 應用程式會根據使用者的驗證狀態和群組成員資格來保護其路由。

若要觀看說明此案例的影片,請參閱 使用應用程式角色、安全性群組、範圍和目錄角色在應用程式中實作授權。

必要條件

  • JDK 版本 8 或更新版本
  • Maven 3
  • Microsoft Entra ID 租用戶。 如需更多資訊,請參閱 如何取得 Microsoft Entra ID 租用戶。
  • 您自己的 Microsoft Entra ID 租用戶中的使用者帳戶。
  • 兩個安全性群組 和 ,其中包含您想要用來測試的使用者。
  • 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/3-Authorization-II/groups

或者,瀏覽至 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-groups)

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

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

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

  2. 選取 新增註冊。

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

    • 在 名稱 區段中,輸入具意義的應用程式名稱,供應用程式使用者查看,例如 。
    • 在 [支援的帳戶類型] 底下,選取 [僅在此組織目錄中的帳戶]。
    • 在 重新導向 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 ] 和 [GroupMember.Read.All ]。 如有需要請使用搜尋方塊。

  18. 選取 新增權限。

  19. 需要管理員同意,因此請選取 授與/撤銷 {tenant} 的管理員同意,然後在系統詢問您是否要針對租用戶中所有帳戶的所要求權限授與同意時,選取 是 您必須是Microsoft Entra ID 租使用者管理員,才能執行此動作。


設定應用程式 (java-servlet-webapp-groups) 以使用您的應用程式註冊

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

注意

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

  1. 在 IDE 中開啟專案。

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

  3. 找出字串 。 如果您是在註冊應用程式時選擇 僅限此組織目錄中的帳戶 選項,請以您的 Microsoft Entra 租用戶識別碼取代現有值。

  4. 尋找字串 ,並將現有值替換為從 Azure 入口網站複製的 應用程式之應用程式識別碼或 。

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

設定安全性群組

您可使用下列選項,進一步設定您的應用程式以接收群組宣告:

  • 取得已登入使用者在 Microsoft Entra ID 租用戶中被指派到的所有群組,包括巢狀群組。 如需更多資訊,請參閱 將您的應用程式設定為接收已指派給已登入使用者的所有群組(包括巢狀群組)一節。

  • 從一組經過篩選且您的應用程式已設定為可搭配使用的群組中,接收群組宣告的值。 如需詳細資訊,請參閱 將您的應用程式設定為接收來自使用者可能被指派到之已篩選群組集合的群組宣告值 一節。 此選項在 Microsoft Entra ID Free 版本中無法使用。

注意

若要取得內部部署群組的 或 ,而非群組 ID,請參閱 使用 Microsoft Entra ID 設定應用程式的群組宣告 中的 使用從 Active Directory 同步的群組屬性之必要條件 一節。

設定您的應用程式以接收已登入使用者指派的所有群組,包括巢狀群組

若要設定您的應用程式,請使用下列步驟:

  1. 在應用程式的註冊頁面上,於導覽窗格中選取 權杖設定,以開啟可設定核發給應用程式之權杖中所提供宣告的頁面。

  2. 選取 [新增群組宣告 ] 以開啟 [ 編輯群組宣告 ] 畫面。

  3. 選取 [安全組] 或 [所有群組] 選項(包括通訊組清單,但不包含指派給應用程式的群組) 選項。 選擇這兩個選項會否定 [安全組] 選項的效果。

  4. 在 ID 區段下,選取 群組 ID。 此選項會使 Microsoft Entra ID 在使用者登入後,於您的應用程式所接收的 ID 權杖 之群組宣告中,傳送已指派給該使用者之群組的 物件識別碼。

將您的應用程式設定為從已篩選的使用者可能被指派群組集合中接收群組宣告值

當下列情況成立時,此選項很有用:

  • 您的應用程式對登入使用者可能指派的一組選取群組感興趣。
  • 您的應用程式不需要關心這位使用者在租用戶中被指派到的每個安全性群組。

此選項可協助您的應用程式避免超額問題。

注意

此功能無法在 Microsoft Entra ID Free 版本 中使用。

使用此選項時,無法使用巢狀群組指派功能。

若要在應用程式中啟用此選項,請使用下列步驟:

  1. 在應用程式的註冊頁面上,於導覽窗格中選取 權杖設定,以開啟可設定核發給應用程式之權杖中所提供宣告的頁面。

  2. 選取 [新增群組宣告 ] 以開啟 [ 編輯群組宣告 ] 畫面。

  3. 選取 指派給應用程式的群組。

    選擇其他選項(例如 安全性群組 或 所有群組(包含通訊群組清單,但不包含指派給應用程式的群組))會抵銷您的應用程式選擇使用此選項所獲得的好處。

  4. 在 ID 區段下,選取 群組 ID。 此選項會使 Microsoft Entra ID 在 ID 權杖 的 groups 宣告中,傳送已指派給使用者之群組的 物件 ID。

  5. 如果您使用 [公開 API] 選項來公開 Web API,則您也可以選擇 [存取] 區段底下的 [群組標識符] 選項。 此選項會使 Microsoft Entra ID 在存取權杖的群組宣告中傳送指派給使用者之群組的物件識別碼。

  6. 在應用程式的註冊頁面上,選取瀏覽窗格中的 [概觀] 以開啟應用程式概觀畫面。

  7. 選取具有本機目錄中受控應用程式中應用程式名稱的超連結。 此欄位標題可能會遭截斷,例如:。 當您選取此連結時,您會前往您建立該應用程式所在租用戶中,與該應用程式服務主體相關聯的 Enterprise Application Overview 頁面。 您可以使用瀏覽器的 [上一頁] 按鈕,巡覽回應用程式註冊頁面。

  8. 選取 瀏覽窗格上的 [使用者和群組 ],以開啟頁面,您可以在其中將使用者和群組指派給應用程式。

  9. 選取新增使用者。

  10. 從隨後顯示的畫面中選取使用者與群組。

  11. 選擇您要指派給此應用程式的群組。

  12. 選取 選取 以完成群組選取。

  13. 選取 [ 指派 ] 以完成群組指派程式。

    當使用者登入您的應用程式是一或多個指派群組的成員時,您的應用程式現在會在群組宣告中接收這些選取的群組。

  14. 選取 瀏覽窗格上的 [屬性 ],以開啟列出應用程式基本屬性的頁面。將 [ 需要使用者指派?] 旗標設定為 [ 是]。

重要

當您將 [需要使用者指派嗎? ] 設定為 [是] 時,Microsoft Entra ID 會檢查 [使用者和群組] 窗格中只有指派給應用程式的使用者能夠登入您的應用程式。 您可以直接指派使用者,或指派他們所屬的安全性群組。

設定應用程式 (java-servlet-webapp-groups) 以辨識群組標識符

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

重要

在 Token Configuration 頁面上,如果您選擇了 groupID 以外的任何選項(例如 DNSDomain\sAMAccountName),則在下列步驟中應輸入群組名稱(例如 ),而不是物件識別碼:

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

  2. 尋找字串 ,並將現有的值取代為您從 Azure 入口網站複製的 群組物件識別碼。 也請將預留位置值中的大括號移除。

  3. 尋找字串 ,並將現有的值取代為您從 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 - 移除祕密值 一節中找到更詳細的指引。 本指南新增將祕密值推送至 金鑰保存庫 並使用 金鑰保存庫 References 的額外步驟。

更新您的 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. 選取 [ 群組 ] 以查看登入使用者之安全組成員資格的任何資訊。
  8. 選取 僅限管理員 或 一般使用者,以存取受群組宣告保護的端點。
    • 如果您的已登入使用者屬於 群組,則可以進入這兩個頁面。
    • 如果已登入的使用者屬於 群組,則該使用者只能進入 一般使用者 頁面。
    • 如果您的登入使用者不是這兩個群組,則用戶無法存取這兩個頁面的其中一個。
  9. 使用角落的按鈕登出。
  10. 登出後,選取 ID Token Details,確認當使用者未獲授權時,應用程式會顯示 錯誤,而不是 ID 權杖宣告內容。

關於程式碼

此範例會使用 MSAL for Java (MSAL4J) 來登入使用者,並取得可能包含群組宣告的標識符令牌。 如果 ID 權杖中可包含的群組過多,此範例會使用 Microsoft Graph SDK for Java 從 Microsoft Graph 取得群組成員資格資料。 根據使用者所屬的群組,已登入的使用者可以存取兩個受保護的頁面 `` 和 `` 中的都不能存取、其中一個,或兩者皆可存取。

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

目錄

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

檔案/資料夾 描述
src/main/java/com/microsoft/azuresamples/msal4j/groupswebapp/ 此目錄包含定義應用程式後端商業規則的類別。
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 參與範例的指導方針。
許可證 範例的授權條款。

處理令牌中的群組宣告,包括處理超額

下列各節說明應用程式如何處理群組宣告。

這些群體聲稱

登入使用者所屬安全組的物件標識碼會在令牌的群組宣告中傳回,如下列範例所示:

{
  ...
  "groups": [
    "0bbe91cc-b69e-414d-85a6-a043d6752215",
    "48931dac-3736-45e7-83e8-015e6dfd6f7c",]
  ...
}

群組超額索賠

為了確保令牌大小不會超過 HTTP 標頭大小限制,Microsoft 身分識別平台 會限制其包含在群組宣告中的物件標識碼數目。

SAML 令牌的超額限製為150,JWT令牌為200,而單頁應用程式則為6。 如果使用者屬於超過超額限制的群組成員,則 Microsoft 身分識別平台 不會在令牌中的群組宣告中發出群組標識符。 而是,它會在權杖中包含超額宣告,指出應用程式應查詢 Microsoft 圖形 API 以擷取使用者的群組成員資格資訊,如下列範例所示:

{
  ...
  "_claim_names": {
    "groups": "src1"
    },
    {
   "_claim_sources": {
    "src1": {
        "endpoint":"[Graph Url to get this user's group membership from]"
        }
    }
  ...
}

在這個範例中建立超額情境以進行測試

若要建立超額情境,您可以使用下列步驟:

  1. 您可以使用 AppCreationScripts 資料夾中提供的 BulkCreateGroups.ps1 檔案來建立大量群組,並將使用者指派給他們。 此檔案用於在開發期間測試超額情境。 請記得變更 BulkCreateGroups.ps1 指令碼中提供的使用者 。

  2. 當您執行此範例並發生超額時,用戶登入後,您會在首頁中看到 _claim_names。

  3. 我們強烈建議您盡可能使用群組篩選功能,以避免發生群組超額。 如需詳細資訊,請參閱 將您的應用程式設定為接收來自使用者可能被指派到之已篩選群組集合的群組宣告值 一節。

  4. 如果您無法避免發生群組超額,建議您使用下列步驟來處理令牌中的群組宣告:

    1. 檢查索賠 _claim_names,確認其中一個值是群組 。 此申請表示已超額。
    2. 如果找到,請呼叫 _claim_sources 中指定的端點,以擷取使用者的群組。
    3. 如果未找到,請查看 groups 宣告以確認使用者所屬的群組。

注意

處理超額宣告需要呼叫 Microsoft Graph 來讀取已登入使用者所屬的群組成員資格,因此您的應用程式必須具備 GroupMember.Read.All 權限,getMemberObjects 函式才能成功執行。

如需 Microsoft Graph 程式設計的詳細資訊,請參閱適用於開發人員的 Microsoft Graph 簡介影片。

ConfidentialClientApplication

系統會在 AuthHelper.java 檔案中建立 執行個體,如下列範例所示。 此物件有助於產生 Microsoft Entra 授權 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);
    

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

    • :為了建置 AuthorizationRequestUrl 而必須設定的參數。
    • :Microsoft Entra 在收集使用者認證後,將瀏覽器重新導向到的位置,並附上授權碼。 它必須與 Azure 入口網站 中 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());
    
    // handle groups overage if it has occurred.
    handleGroupsOverage(contextAdapter);
    
  5. 完成上一個步驟後,您可以使用 的執行個體呼叫 來擷取群組成員資格。

  6. 如果使用者屬於太多群組(超過 200 個),那麼若不是因為呼叫 ,對 的呼叫可能會是空的。 同時, 會傳回 ,表示已發生超額情況,而若要取得完整的群組清單,則需要呼叫 Microsoft Graph。 請參閱 AuthHelper.java 中的 方法,了解此應用程式在發生超額情況時如何使用 。

保護路由

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

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

在 下以逗號分隔的規則集中所列的任何路由,也都禁止未驗證的已驗證使用者存取,如以下範例所示。 不過,這些路徑也包含以空格分隔的群組成員身分清單。 只有屬於至少一個對應群組的使用者才能在驗證之後存取這些路由。

# define short names for group IDs here for the app. This is useful in the next property (app.protect.groups).
# EXCLUDE the curly braces, they are in this file only as delimiters.
# example:
# app.groups=groupA abcdef-qrstuvw-xyz groupB abcdef-qrstuv-wxyz
app.groups=admin {enter-your-admins-group-id-here}, user {enter-your-users-group-id-here}

# A route and its corresponding group(s) that can view it, <space-separated>; the start of the next route & its group(s) is delimited by a <comma-and-space-separator>
# this says: /admins_only can be accessed by admin group, /regular_user can be accessed by admin group and user group
app.protect.groups=/admin_only admin, /regular_user admin user

範圍

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

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

如需應用程式要求的範圍,請參閱 authentication.properties。 預設情況下,應用程式會將 scopes 值設為 。 如果應用程式需要呼叫 Graph 以取得使用者的群組成員資格,則需要此特定Microsoft 圖形 API 範圍。

其他相關資訊

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