使用 Azure Active Directory B2C 保護 Java Spring Boot 應用程式
本文示範 Java Spring Boot Web 應用程式,其會使用適用於 Java 的 Azure AD B2C Spring Boot Starter 用戶端連結庫,登入 Azure Active Directory B2C 租使用者上的使用者。 它會使用 OpenID Connect 通訊協定。
下圖顯示應用程式的拓撲:
用戶端應用程式會使用適用於 Java 的 Azure AD B2C Spring Boot Starter 用戶端連結庫來登入使用者,並從 Azure AD B2C 取得識別符令牌。 標識元令牌會證明使用者已向 Azure AD B2C 進行驗證,並讓使用者存取受保護的路由。
必要條件
- JDK 第 15 版。 此範例是在 Java 15 的系統上開發,但可能與其他版本相容。
- Maven 3
- 建議使用適用於Visual Studio Code的 Java 擴充套件,在Visual Studio Code 中執行此範例。
- Azure AD B2C 租使用者。 如需詳細資訊,請參閱 教學課程:建立 Azure Active Directory B2C 租使用者
- Visual Studio Code
- 適用於 Visual Studio Code 的 Azure 工具
建議
- 一些熟悉 Spring Framework。
- 一些熟悉 Linux/OSX 終端機。
- jwt.ms 檢查令牌。
- Fiddler 用於監視您的網路活動和疑難解答。
- 請遵循Microsoft Entra ID 部落格,隨時掌握最新的發展。
設定範例
下列各節說明如何設定範例應用程式。
複製或下載範例存放庫
若要複製範例,請開啟Bash視窗,並使用下列命令:
git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 4-spring-web-app/1-Authentication/sign-in-b2c
或者,流覽至 ms-identity-msal-java-samples 存放庫,然後將它下載為 .zip 檔案,並將其解壓縮至您的硬碟。
重要
若要避免 Windows 上的檔案路徑長度限制,請將存放庫複製到硬碟根目錄附近的目錄中。
此範例隨附預先註冊的應用程式以供示範之用。 如果您想要使用自己的 Azure AD B2C 租使用者和應用程式,請在 Azure 入口網站 中註冊並設定應用程式。 如需詳細資訊,請參閱 註冊應用程式 一節。 否則,請繼續進行執行範例一節中的步驟。
選擇您想要在其中建立應用程式的 Azure AD B2C 租使用者
若要選擇您的租使用者,請使用下列步驟:
登入 Azure 入口網站。
如果您的帳戶存在於多個 Azure AD B2C 租使用者中,請在 Azure 入口網站 的角落選取您的配置檔,然後選取 [切換目錄] 將會話變更為所需的 Azure AD B2C 租使用者。
建立使用者流程和自定義原則
若要建立常見的使用者流程,例如註冊、登入、配置檔編輯和密碼重設,請參閱 教學課程:在 Azure Active Directory B2C 中建立使用者流程。
您也應該考慮在 Azure Active Directory B2C 中建立自定義原則。 不過,此工作已超出本教學課程的範圍。 如需詳細資訊,請參閱 Azure AD B2C 自定義原則概觀。
新增外部識別提供者
請參閱 教學課程:在 Azure Active Directory B2C 中將識別提供者新增至您的應用程式。
註冊應用程式 (java-spring-webapp-auth-b2c)
若要註冊應用程式,請使用下列步驟:
流覽至 Azure 入口網站,然後選取 [Azure AD B2C]。
在瀏覽窗格中選取 [應用程式註冊 ],然後選取 [ 新增註冊]。
在出現的 [ 註冊應用程式] 頁面中 ,輸入下列應用程式註冊資訊:
- 在 [ 名稱] 區段中,輸入有意義的應用程式名稱,以顯示給應用程式的使用者 ,例如
java-spring-webapp-auth-b2c
。 - 在 [支援的帳戶類型] 下,選取 [任何身分識別提供者或組織目錄中的帳戶 (用於運用使用者流程來驗證使用者)]。
- 在 [ 重新導向 URI (選擇性)] 區段中,選取 下拉式方塊中的 [Web ],然後輸入下列重新導向 URI:
http://localhost:8080/login/oauth2/code/
。
- 在 [ 名稱] 區段中,輸入有意義的應用程式名稱,以顯示給應用程式的使用者 ,例如
選取 [暫存器] 以建立應用程式。
在應用程式的註冊頁面上,尋找並複製 應用程式 (用戶端) 識別碼 值,以供稍後使用。 您會在應用程式的組態檔或檔案中使用此值。
選取儲存以儲存變更。
在應用程式的註冊頁面上,選取 瀏覽窗格中的 [憑證和秘密 ] 窗格,以開啟頁面以產生秘密並上傳憑證。
在用戶端密碼區段底下,選取新增用戶端密碼。
輸入描述 - 例如, 應用程式秘密。
根據您的安全性考慮選取其中一個可用的持續時間,例如, 在2年內。
選取 [新增]。 產生的值隨即顯示。
複製並儲存產生的值,以供後續步驟使用。 您需要此值才能用於程式代碼的組態檔。 此值不會再次顯示,而且您無法透過任何其他方式加以擷取。 因此,請務必先從 Azure 入口網站 儲存它,再流覽至任何其他畫面或窗格。
設定應用程式 (java-spring-webapp-auth-b2c) 以使用您的應用程式註冊
使用下列步驟來設定應用程式:
注意
在下列步驟中,ClientID
與 或 AppId
相同Application ID
。
在 IDE 中開啟專案。
開啟 src/main/resources/application.yml 檔案。
尋找 屬性,
client-id
並將現有的值取代為應用程式標識碼或clientId
java-spring-webapp-auth-b2c
應用程式 Azure 入口網站。尋找 屬性,
client-secret
並將現有的值取代為您在從 Azure 入口網站 建立java-spring-webapp-auth-b2c
應用程式期間儲存的值。base-uri
尋找 屬性,並將值的fabrikamb2c
兩個實例取代為您在 Azure 入口網站 中建立java-spring-webapp-auth-b2c
應用程式的 Azure AD B2C 租用戶名稱。sign-up-or-sign-in
尋找 屬性,並將它取代為您在 azure AD B2C 租使用者中建立的註冊/登入使用者流程原則名稱,您在其中在 Azure 入口網站 中建立java-spring-webapp-auth-b2c
應用程式。profile-edit
尋找 屬性,並將它取代為您在 azure AD B2C 租使用者中建立的應用程式在 Azure 入口網站 中建立java-spring-webapp-auth-b2c
的應用程式名稱。password-reset
尋找 屬性,並將它取代為您在 azure AD B2C 租使用者中建立的編輯配置檔使用者流程原則名稱,您在 Azure 入口網站 中建立java-spring-webapp-auth-b2c
應用程式。開啟 src/main/resources/templates/navbar.html 檔案。
尋找和
b2c_1_edit_profile
流程的參考,b2c_1_susi
並以您的sign-up-sign-in
和profile-edit
使用者流程取代它們。
執行範例
下列各節說明如何將範例部署至 Azure Container Apps。
必要條件
- Azure 帳戶。 如果您沒有訂用帳戶,請建立免費帳戶。 您需要 Azure 訂用帳戶的「參與者」或「擁有者」權限才能繼續。 如需詳細資訊,請參閱使用 Azure 入口網站指派 Azure 角色。
- Azure CLI。
- Azure Container Apps CLI 擴充功能、版本或更新版本
0.3.47
。 若要安裝最新版本,請使用az extension add --name containerapp --upgrade --allow-preview
命令。 - Java 開發工具組 17 版或更高版本。
- Maven.
準備 Spring 專案
使用下列步驟來準備專案:
使用下列 Maven 命令來建置專案:
mvn clean verify
使用下列命令在本機執行範例專案:
mvn spring-boot:run
設定
若要從 CLI 登入 Azure,請執行下列命令並遵循提示來完成驗證流程。
az login
若要確定您執行的是最新版本 CLI,請執行升級命令。
az upgrade
接下來,安裝或更新 CLI 的 Azure 容器應用程式延伸模組。
如果您在 Azure CLI 中執行 az containerapp
命令時收到遺漏參數的錯誤,請確定您已安裝最新版的 Azure Container Apps 擴充功能。
az extension add --name containerapp --upgrade
注意
從 2024 年 5 月開始,Azure CLI 延伸模組預設不會再啟用預覽功能。 若要存取容器應用程式預覽功能,請使用 --allow-preview true
安裝容器應用程式延伸模組。
az extension add --name containerapp --upgrade --allow-preview true
現在已安裝目前的延伸模組或模組,請註冊 Microsoft.App
和 Microsoft.OperationalInsights
命名空間。
注意
Azure 容器應用程式資源已從 Microsoft.Web
命名空間移轉至 Microsoft.App
命名空間。 如需詳細資訊,請參閱 2022 年 3 月將命名空間從 Microsoft.Web 移轉至 Microsoft.App。
az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights
建立 Azure Container Apps 環境
現在您的 Azure CLI 設定已完成,接下來您可以定義本文中使用的環境變數了。
在您的 Bash 殼層中定義下列變數。
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 Container Apps 時,您的重新導向 URL 會變更為 Azure Container Apps 中已部署應用程式實例的重新導向 URL。 使用下列步驟來變更application.yml檔案中的這些設定:
流覽至應用程式的 src\main\resources\application.yml 檔案,並將 的值
post-logout-redirect-uri
變更為已部署應用程式的功能變數名稱,如下列範例所示。 請務必以您的實際值取代<API_NAME>
和<default-domain-of-container-app-environment>
。 例如,使用上一個步驟中 Azure Container App 環境的預設網域,以及ms-identity-api
針對您的應用程式名稱,您將用於https://ms-identity-api.<default-domain>
post-logout-redirect-uri
值。post-logout-redirect-uri: https://<API_NAME>.<default-domain-of-container-app-environment>
儲存此檔案之後,請使用下列命令重建您的應用程式:
mvn clean package
重要
應用程式的 application.yml 檔案目前在 參數中 client-secret
保留客戶端密碼的值。 將此值保留在這個檔案中並不好的做法。 如果您將檔案認可至 Git 存放庫,您可能也會冒險。 如需建議的方法,請參閱 管理 Azure Container Apps 中的秘密。
更新您的 Microsoft Entra ID 應用程式註冊
由於重新導向 URI 會變更至 Azure Container Apps 上已部署的應用程式,因此您也需要變更 Microsoft Entra ID 應用程式註冊中的重新導向 URI。 請使用下列步驟來進行此變更:
流覽至 適用於開發人員的 Microsoft 身分識別平台 應用程式註冊 頁面。
使用搜尋方塊來搜尋您的應用程式註冊 ,例如
java-servlet-webapp-authentication
。選取應用程式名稱以開啟您的應用程式註冊。
從選單中選擇 驗證。
在 [Web - 重新導向 URI] 區段中,選取 [新增 URI]。
填寫應用程式的 URI,並附加
/login/oauth2/code/
-例如https://<containerapp-name>.<default domain of container app environment>/login/oauth2/code/
。選取儲存。
部署應用程式
將 JAR 套件部署至 AAzure 容器應用程式。
注意
如有必要,您可以在 Java 建置環境變數中指定 JDK 版本。 如需詳細資訊,請參閱 在 Azure Container Apps 中建置 Java 的環境變數。
現在您可以使用 az containerapp up
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 版本以與您的應用程式相容,可以使用 --build-env-vars BP_JVM_VERSION=<YOUR_JDK_VERSION>
引數來調整版本號碼。
如需更多建置環境變數,請參閱 在 Azure Container Apps 中建置 Java 的環境變數。
驗證應用程式
在此範例中 containerapp up
,命令包含 --query properties.configuration.ingress.fqdn
自變數,其會傳回完整功能變數名稱 (FQDN),也稱為應用程式的 URL。 使用下列步驟來檢查應用程式的記錄,以調查任何部署問題:
從 [部署] 區段的 [輸出] 頁面存取輸出應用程式 URL。
從 [Azure Container Apps 實例 概觀 ] 頁面的瀏覽窗格中,選取 [ 記錄 ] 以檢查應用程式的記錄。
探索範例
使用下列步驟來探索範例:
- 請注意畫面中央顯示的已登入或註銷狀態。
- 選取角落中的上下文相關按鈕。 當您第一次執行應用程式時,此按鈕會 讀取 [登入 ]。 或者,選取令牌詳細數據的連結。 由於此頁面受到保護且需要驗證,因此會自動重新導向至登入頁面。
- 在下一個頁面上,遵循指示,並使用所選身分識別提供者的帳戶登入。 您也可以選擇使用電子郵件地址註冊或登入 B2C 租使用者上的本機帳戶。
- 順利完成登入流程時,您應該重新導向至首頁 -- 顯示 登入狀態 - 或 令牌詳細 數據頁面,視觸發登入流程的按鈕而定。
- 請注意,上下文相關按鈕現在會顯示 [註銷 ] 並顯示您的用戶名稱。
- 如果您是在首頁上,請選取 [標識符令牌詳細數據 ],以查看部分標識符令牌已譯碼的宣告。
- 編輯您的配置檔。 選取 [編輯配置檔 ] 以變更詳細數據,例如您的顯示名稱、居住地和職業。
- 使用角落中的按鈕註銷。狀態頁面會反映新狀態。
關於程式碼
此範例示範如何使用 適用於 Java 的 Azure AD B2C Spring Boot Starter 用戶端連結庫,將使用者登入您的 Azure AD B2C 租使用者。 此範例也會使用 Spring Oauth2 用戶端和 Spring Web 開機入門。 此範例會使用從 Azure AD B2C 取得之標識碼令牌的宣告來顯示登入使用者的詳細數據。
目錄
下表顯示範例項目資料夾的內容:
檔案/資料夾 | 描述 |
---|---|
pom.xml | 應用程式相依性。 |
src/main/resources/templates/ | 適用於 UI 的 Thymeleaf 範本。 |
src/main/resources/application.yml | 應用程式和Microsoft Entra Boot Starter 連結庫組態。 |
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ | 此目錄包含主要應用程式進入點、控制器和設定類別。 |
.../MsIdentitySpringBootWebappApplication.java | 主要類別。 |
.../SampleController.java | 具有端點對應的控制器。 |
.../SecurityConfig.java | 安全性設定 - 例如,需要驗證的路由。 |
.../Utilities.java | 公用程式類別 - 例如篩選識別碼令牌宣告。 |
CHANGELOG.md | 範例的變更清單。 |
CONTRIBUTING.md | 參與範例的指導方針。 |
許可證 | 範例的授權。 |
標識元令牌宣告
若要擷取令牌詳細數據,應用程式會在要求對應中使用 Spring Security 的 AuthenticationPrincipal
和 OidcUser
物件,如下列範例所示,如下列範例所示。 如需此應用程式如何使用標識元令牌宣告的完整詳細數據,請參閱範例控制器。
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();
}
登入和註銷連結
針對登入,應用程式會向適用於 Java 的 Azure AD B2C Spring Boot Starter 用戶端連結庫自動設定的 Azure AD B2C 登入端點提出要求,如下列範例所示:
<a class="btn btn-success" href="/oauth2/authorization/{your-sign-up-sign-in-user-flow}">Sign In</a>
針對註銷,應用程式會向 logout
端點提出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>
使用 WebSecurityConfigurerAdapter 保護路由
根據預設,應用程式會保護 [ 標識符令牌詳細 數據] 頁面,以便只有登入的使用者才能存取它。 應用程式會從 application.yml 檔案中的 app.protect.authenticated
屬性設定這些路由。 若要設定應用程式的特定需求,您可以在其中一個類別中擴充 WebSecurityConfigurerAdapter
。 如需範例,請參閱此應用程式的 SecurityConfig 類別,如下列程式代碼所示:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${app.protect.authenticated}")
private String[] protectedRoutes;
private final AADB2COidcLoginConfigurer configurer;
public SecurityConfig(AADB2COidcLoginConfigurer configurer) {
this.configurer = configurer;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.authorizeRequests()
.antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details)
.antMatchers("/**").permitAll() // allow all other routes.
.and()
.apply(configurer)
;
// @formatter:off
}
}
其他相關資訊
- Microsoft 身分識別平台 (適用於開發人員的Microsoft項目識別碼)
- Microsoft驗證連結庫概觀 (MSAL)
- 快速入門:使用 Microsoft 身分識別平台來註冊應用程式
- 快速入門:設定用戶端應用程式以存取 Web API
- 瞭解Microsoft Entra ID 應用程式同意體驗
- 瞭解使用者和系統管理員同意
- Microsoft Entra 中的應用程式和服務主體物件 (機器翻譯)
- 國家雲端
- MSAL 程式代碼範例
- Microsoft適用於 Java 的 Entra ID Spring Boot Starter 用戶端連結庫
- 適用於 Java 的 Azure Active Directory B2C Spring Boot Starter 用戶端連結庫
- Microsoft Java 驗證連結庫 (MSAL4J)
- MSAL4J Wiki
- 識別碼權杖
- Microsoft 身分識別平台內的存取權杖
如需 OAuth 2.0 通訊協定在此案例和其他案例中運作方式的詳細資訊,請參閱 Microsoft Entra ID 的驗證案例。