共用方式為


spring Boot Starter for Microsoft Entra developer's guide

本文適用於: ✔️版本 4.19.0 ✔️ 5.14.0

本文說明 Spring Boot Starter for Microsoft Entra ID 的功能和核心案例。 本文也包含常見問題、因應措施和診斷步驟的指引。

當您建置 Web 應用程式時,身分識別和存取管理是基本部分。 Azure 提供雲端式身分識別服務,其與 Azure 生態系統的其餘部分具有深度整合。

雖然 Spring Security 可讓您輕鬆地保護您的 Spring 型應用程式,但不會針對特定的身分識別提供者量身打造。 Microsoft Entra 識別符的 Spring Boot Starter 可讓您將 Web 應用程式連線到 Microsoft Entra 租使用者,並使用 Microsoft Entra ID 保護您的資源伺服器。 它會使用 Oauth 2.0 通訊協定來保護 Web 應用程式和資源伺服器。

下列連結提供入門套件、檔和範例的存取權:

必要條件

若要遵循本指南中的指示,您必須具備下列必要條件:

重要

需要 Spring Boot 2.5 版或更高版本,才能完成本文中的步驟。

核心案例

本指南說明如何在下列案例中使用 Microsoft Entra 入門版:

Web 應用程式是任何可讓使用者登入的 Web 應用程式。 驗證存取令牌之後,資源伺服器將會接受或拒絕存取。

存取 Web 應用程式

此案例使用 OAuth 2.0 授權碼授 與流程,讓用戶能夠使用Microsoft帳戶登入。

若要在此案例中使用 Microsoft Entra 入門版,請使用下列步驟:

將重新導向 URI 設定為 application-base-uri>/login/oauth2/code/。< 例如: http://localhost:8080/login/oauth2/code/ 。 請務必包含尾端 /。 如需重新導向 URI 的詳細資訊,請參閱快速入門:使用 Microsoft 身分識別平台 註冊應用程式。

Azure 入口網站 的螢幕快照,其中顯示已醒目提示重新導向 URI 的 Web 應用程式驗證頁面。

將下列相依性新增至您的 pom.xml 檔案。

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

注意

如需如何使用材料帳單來管理 Spring Cloud Azure 連結庫版本的詳細資訊,請參閱 Spring Cloud Azure 開發人員指南快速入門一節。

將下列屬性新增至 application.yml 檔案。 您可以從您在 Azure 入口網站 中建立的應用程式註冊取得這些屬性的值,如必要條件中所述。

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <your-client-ID>
         client-secret: <your-client-secret>

注意

允許 tenant-id 的值包括: commonorganizationsconsumers或租用戶標識碼。 如需這些值的詳細資訊,請參閱 使用錯誤的端點(個人和組織帳戶) 一節錯誤 AADSTS50020 - 來自識別提供者的用戶帳戶不存在於租使用者中。 如需轉換單一租使用者應用程式的資訊,請參閱 將單一租使用者應用程式轉換成Microsoft Entra 標識碼上的多租使用者。

使用預設安全性設定或提供您自己的設定。

選項 1:使用預設組態。

使用此選項時,您不需要執行任何動作。 類別 DefaultAadWebSecurityConfigurerAdapter 會自動設定。

選項 2:提供自我定義的組態。

若要提供組態,請擴充 AadWebSecurityConfigurerAdapter 類別並在 函式中configure(HttpSecurity http)呼叫super.configure(http),如下列範例所示:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {

   /**
    * Add configuration logic as needed.
   */
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       super.configure(http);
       http.authorizeRequests()
           .anyRequest().authenticated();
       // Do some custom configuration.
   }
}

從 Web 應用程式存取資源伺服器

若要在此案例中使用 Microsoft Entra 入門版,請使用下列步驟:

如先前所述,設定重新導向 URI。

將下列相依性新增至您的 pom.xml 檔案。

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

注意

如需如何使用材料帳單來管理 Spring Cloud Azure 連結庫版本的詳細資訊,請參閱 Spring Cloud Azure 開發人員指南快速入門一節。

將下列屬性新增至 application.yml 檔案,如先前所述:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <your-client-ID>
         client-secret: <your-client-secret>
       authorization-clients:
         graph:
           scopes: https://graph.microsoft.com/Analytics.Read, email

注意

允許 tenant-id 的值包括: commonorganizationsconsumers或租用戶標識碼。 如需這些值的詳細資訊,請參閱 使用錯誤的端點(個人和組織帳戶) 一節錯誤 AADSTS50020 - 來自識別提供者的用戶帳戶不存在於租使用者中。 如需轉換單一租使用者應用程式的資訊,請參閱 將單一租使用者應用程式轉換成Microsoft Entra 標識碼上的多租使用者。

以下是您 OAuth2AuthorizedClient的名稱,graph而且scopes是登入時需要同意的範圍。

將程式代碼新增至您的應用程式,類似於下列範例:

@GetMapping("/graph")
@ResponseBody
public String graph(
   @RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graphClient
) {
   // toJsonString() is just a demo.
   // oAuth2AuthorizedClient contains access_token. We can use this access_token to access the resource server.
   return toJsonString(graphClient);
}

graph以下是在上一個步驟中設定的用戶端標識碼。 OAuth2AuthorizedClient 包含存取令牌,用來存取資源伺服器。

如需示範此案例的完整範例,請參閱 spring-cloud-azure-starter-active-directory 範例:aad-web-application

保護資源伺服器/API

此案例不支援登入,但藉由驗證存取令牌來保護伺服器。 如果存取令牌有效,伺服器會提供要求。

若要在此案例中使用 Microsoft Entra 入門版,請使用下列步驟:

將下列相依性新增至您的 pom.xml 檔案。

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

注意

如需如何使用材料帳單來管理 Spring Cloud Azure 連結庫版本的詳細資訊,請參閱 Spring Cloud Azure 開發人員指南快速入門一節。

將下列屬性新增至 application.yml 檔案,如先前所述:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       credential:
         client-id: <your-client-ID>
       app-id-uri: <your-app-ID-URI>

您可以使用 your-client-ID> 和< your-app-ID-URI> 值來驗證存取令牌。< 您可以從 Azure 入口網站 取得 <your-app-ID-URI> 值,如下圖所示:

Azure 入口網站 的螢幕快照,其中顯示已醒目提示 [應用程式標識符 URI] 的 Web 應用程式 [公開 API] 頁面。

使用預設安全性設定或提供您自己的設定。

選項 1:使用預設組態。

使用此選項時,您不需要任何專案。 類別 DefaultAadResourceServerWebSecurityConfigurerAdapter 會自動設定。

選項 2:提供自我定義的組態。

若要提供組態,請擴充 AadResourceServerWebSecurityConfigurerAdapter 類別並在 函式中configure(HttpSecurity http)呼叫super.configure(http),如下列範例所示:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2ResourceServerSecurityConfig extends AadResourceServerWebSecurityConfigurerAdapter {

   /**
    * Add configuration logic as needed.
    */
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       super.configure(http);
       http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
   }
}

如需示範此案例的完整範例,請參閱 spring-cloud-azure-starter-active-directory 範例:aad-resource-server

從資源伺服器存取其他資源伺服器

此案例支援造訪其他資源伺服器的資源伺服器。

若要在此案例中使用 Microsoft Entra 入門版,請使用下列步驟:

將下列相依性新增至您的 pom.xml 檔案。

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

注意

如需如何使用材料帳單來管理 Spring Cloud Azure 連結庫版本的詳細資訊,請參閱 Spring Cloud Azure 開發人員指南快速入門一節。

將下列屬性新增至 application.yml 檔案:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <web-API-A-client-ID>
         client-secret: <web-API-A-client-secret>
       app-id-uri: <web-API-A-app-ID-URI>
       authorization-clients:
         graph:
           scopes:
              - https://graph.microsoft.com/User.Read

注意

允許 tenant-id 的值包括: commonorganizationsconsumers或租用戶標識碼。 如需這些值的詳細資訊,請參閱 使用錯誤的端點(個人和組織帳戶) 一節錯誤 AADSTS50020 - 來自識別提供者的用戶帳戶不存在於租使用者中。 如需轉換單一租使用者應用程式的資訊,請參閱 將單一租使用者應用程式轉換成Microsoft Entra 標識碼上的多租使用者。

@RegisteredOAuth2AuthorizedClient使用程式代碼中的 屬性來存取相關的資源伺服器,如下列範例所示:

@PreAuthorize("hasAuthority('SCOPE_Obo.Graph.Read')")
@GetMapping("call-graph")
public String callGraph(@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graph) {
   return callMicrosoftGraphMeEndpoint(graph);
}

如需示範此案例的完整範例,請參閱 spring-cloud-azure-starter-active-directory 範例:aad-resource-server-obo

一個應用程式中的 Web 應用程式和資源伺服器

此案例支援 存取 Web 應用程式 ,並在 一個應用程式中保護資源伺服器/API

aad-starter若要在此案例中使用,請遵循下列步驟:

將下列相依性新增至您的 pom.xml 檔案。

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

注意

如需如何使用材料帳單來管理 Spring Cloud Azure 連結庫版本的詳細資訊,請參閱 Spring Cloud Azure 開發人員指南快速入門一節。

更新您的 application.yml 檔案。 將屬性 spring.cloud.azure.active-directory.application-type 設定為 web_application_and_resource_server,並指定每個授權客戶端的授權類型,如下列範例所示。

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       profile:
         tenant-id: <tenant>
       credential:
         client-id: <Web-API-C-client-id>
         client-secret: <Web-API-C-client-secret>
       app-id-uri: <Web-API-C-app-id-url>
       application-type: web_application_and_resource_server  # This is required.
       authorization-clients:
         graph:
           authorizationGrantType: authorization_code  # This is required.
           scopes:
             - https://graph.microsoft.com/User.Read
             - https://graph.microsoft.com/Directory.Read.All

注意

允許 tenant-id 的值包括: commonorganizationsconsumers或租用戶標識碼。 如需這些值的詳細資訊,請參閱 使用錯誤的端點(個人和組織帳戶) 一節錯誤 AADSTS50020 - 來自識別提供者的用戶帳戶不存在於租使用者中。 如需轉換單一租使用者應用程式的資訊,請參閱 將單一租使用者應用程式轉換成Microsoft Entra 標識碼上的多租使用者。

撰寫 Java 程式代碼來設定多個 HttpSecurity 實例。

在下列範例程式代碼中, AadWebApplicationAndResourceServerConfig 包含兩個安全性組態、一個用於資源伺服器,另一個用於 Web 應用程式。 類別 ApiWebSecurityConfigurationAdapter 具有高優先順序來設定資源伺服器安全性配接器。 類別 HtmlWebSecurityConfigurerAdapter 的優先順序較低,可用來設定 Web 應用程式安全性配接器。

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadWebApplicationAndResourceServerConfig {

   @Order(1)
   @Configuration
   public static class ApiWebSecurityConfigurationAdapter extends AadResourceServerWebSecurityConfigurerAdapter {
       protected void configure(HttpSecurity http) throws Exception {
           super.configure(http);
           // All the paths that match `/api/**`(configurable) work as the esource server. Other paths work as  the web application.
           http.antMatcher("/api/**")
               .authorizeRequests().anyRequest().authenticated();
       }
   }

   @Configuration
   public static class HtmlWebSecurityConfigurerAdapter extends AadWebSecurityConfigurerAdapter {

       @Override
       protected void configure(HttpSecurity http) throws Exception {
           super.configure(http);
           // @formatter:off
           http.authorizeRequests()
                   .antMatchers("/login").permitAll()
                   .anyRequest().authenticated();
           // @formatter:on
       }
   }
}

應用程式類型

屬性 spring.cloud.azure.active-directory.application-type 是選擇性的,因為其值可由相依性推斷。 只有當您使用 web_application_and_resource_server 值時,才必須手動設定 屬性。

具有相依性:spring-security-oauth2-client 具有相依性:spring-security-oauth2-resource-server 應用程式類型的有效值 預設值
web_application web_application
.是 resource_server resource_server
.是 Yes web_applicationresource_server
resource_server_with_obo, web_application_and_resource_server
resource_server_with_obo

可設定的屬性

Microsoft Entra 標識符的 Spring Boot Starter 提供下列屬性:

屬性 描述
spring.cloud.azure.active-directory.app-id-uri 資源伺服器用來驗證存取令牌中的物件。 只有在物件等於your-client-ID><先前所述的your-app-ID-URI>值時,存取令牌才有效。<
spring.cloud.azure.active-directory.authorization-clients 設定應用程式即將造訪之資源 API 的對應。 每個項目都會對應到應用程式將流覽的一個資源 API。 在您的 Spring 程式代碼中,每個專案都會對應至一個 OAuth2AuthorizedClient 物件。
spring.cloud.azure.active-directory.authorization-clients。<your-client-name.scopes> 應用程式將取得之資源伺服器的 API 許可權。
spring.cloud.azure.active-directory.authorization-clients。<your-client-name.authorization-grant-type> 授權客戶端的類型。 支援的類型為 authorization_code (webapp 的默認類型)、 on_behalf_of (resource-server 的默認類型), client_credentials
spring.cloud.azure.active-directory.application-type 請參閱應用程式類型
spring.cloud.azure.active-directory.profile.environment.active-directory-endpoint 授權伺服器的基底 URI。 預設值是 https://login.microsoftonline.com/
spring.cloud.azure.active-directory.credential.client-id Microsoft Entra ID 中已註冊的應用程式識別碼。
spring.cloud.azure.active-directory.credential.client-secret 已註冊應用程式的客戶端密碼。
spring.cloud.azure.active-directory.user-group.use-transitive-members 如果設定為 true,請使用 v1.0/me/transitiveMemberOf 來取得群組。 否則,請使用 /v1.0/me/memberOf
spring.cloud.azure.active-directory.post-logout-redirect-uri 用於張貼註銷的重新導向URI。
spring.cloud.azure.active-directory.profile.tenant-id Azure 租用戶標識碼。 允許 tenant-id 的值包括: commonorganizationsconsumers或租用戶標識碼。
spring.cloud.azure.active-directory.user-group.allowed-group-names 如果從 Graph API 呼叫的 MemberOf 回應中找到授權單位,則會將授權單位授與的預期使用者群組。
spring.cloud.azure.active-directory.user-name-attribute 指出哪個宣告會是主體的名稱。

下列範例示範如何使用這些屬性:

屬性範例 1: 若要使用 Azure China 21Vianet 而非 Azure Global,請使用下列步驟。

  • 將下列屬性新增至 application.yml 檔案:

    spring:
       cloud:
         azure:
           active-directory:
             enabled: true
             profile:
               environment:
                 active-directory-endpoint: https://login.partner.microsoftonline.cn
    

透過此方法,您可以使用 Azure 主權或國家雲端 ,而不是 Azure 公用雲端。

屬性範例 2: 若要使用組名來保護 Web 應用程式中的某些方法,請使用下列步驟:

將下列屬性新增至您的 application.yml 檔案:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       user-group:
         allowed-groups: group1, group2

使用預設安全性設定或提供您自己的設定。

選項 1:使用預設組態。 使用此選項時,您不需要執行任何動作。 類別 DefaultAadWebSecurityConfigurerAdapter 會自動設定。

選項 2:提供自我定義的組態。 若要提供組態,請擴充 AadWebSecurityConfigurerAdapter 類別並在 函式中configure(HttpSecurity http)呼叫super.configure(http),如下列範例所示:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {

   /**
    * Add configuration logic as needed.
    */
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       super.configure(http);
       http.authorizeRequests()
           .anyRequest().authenticated();
       // Do some custom configuration.
   }
}

@PreAuthorize使用 註釋來保護 方法,如下列範例所示:

@Controller
public class RoleController {
   @GetMapping("group1")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_group1')")
   public String group1() {
       return "group1 message";
   }

   @GetMapping("group2")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_group2')")
   public String group2() {
       return "group2 message";
   }

   @GetMapping("group1Id")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_<group1-id>')")
   public String group1Id() {
       return "group1Id message";
   }

   @GetMapping("group2Id")
   @ResponseBody
   @PreAuthorize("hasRole('ROLE_<group2-id>')")
   public String group2Id() {
       return "group2Id message";
   }
}

屬性範例 3: 若要在造訪資源伺服器的資源伺服器中啟用客戶端認證流程,請使用下列步驟:

將下列屬性新增至您的 application.yml 檔案:

spring:
 cloud:
   azure:
     active-directory:
       enabled: true
       authorization-clients:
         webapiC:   # When authorization-grant-type is null, on behalf of flow is used by default
           authorization-grant-type: client_credentials
           scopes:
             - <Web-API-C-app-id-url>/.default

將程式代碼新增至您的應用程式,類似於下列範例:

@PreAuthorize("hasAuthority('SCOPE_Obo.WebApiA.ExampleScope')")
@GetMapping("webapiA/webapiC")
public String callClientCredential() {
   String body = webClient
       .get()
       .uri(CUSTOM_LOCAL_READ_ENDPOINT)
       .attributes(clientRegistrationId("webapiC"))
       .retrieve()
       .bodyToMono(String.class)
       .block();
   LOGGER.info("Response from Client Credential: {}", body);
   return "client Credential response " + (null != body ? "success." : "failed.");
}

進階功能

在 Web 應用程式中支援依標識碼令牌進行存取控制

入門版支援從標識元令牌的roles宣告建立GrantedAuthority,以允許在 Web 應用程式中使用標識碼令牌進行授權。 您可以使用 appRoles Microsoft Entra ID 的功能來建立 roles 宣告並實作訪問控制。

注意

rolesappRoles 產生的宣告會以前置詞 APPROLE_裝飾。

使用 appRoles 做為 roles 宣告時,請避免同時將群組屬性設定為 roles 。 否則,群組屬性會覆寫宣告以包含群組資訊, appRoles而不是 。 您應該避免在指令清單中設定下列設定:

"optionalClaims": {
    "idtoken": [{
        "name": "groups",
        "additionalProperties": ["emit_as_roles"]
    }]
}

若要在 Web 應用程式中支援依識別元令牌進行存取控制,請使用下列步驟:

在應用程式中新增應用程式角色,並將其指派給使用者或群組。 如需詳細資訊,請參閱 如何:將應用程式角色新增至您的應用程式,並在令牌中接收它們。

將下列 appRoles 組態新增至應用程式的指令清單:

 "appRoles": [
   {
     "allowedMemberTypes": [
       "User"
     ],
     "displayName": "Admin",
     "id": "2fa848d0-8054-4e11-8c73-7af5f1171001",
     "isEnabled": true,
     "description": "Full admin access",
     "value": "Admin"
    }
 ]

將程式代碼新增至您的應用程式,類似於下列範例:

@GetMapping("Admin")
@ResponseBody
@PreAuthorize("hasAuthority('APPROLE_Admin')")
public String Admin() {
   return "Admin message";
}

疑難排解

啟用用戶端記錄

適用於 Java 的 Azure SDK 提供一致的記錄案例,以協助疑難解答和解決應用程式錯誤。 產生的記錄會在到達終端之前擷取應用程式的流程,以協助找出根問題。 檢視 記錄 Wiki,以取得啟用記錄的指引。

啟用 Spring 記錄

Spring 可讓所有支援的記錄系統在 Spring 環境中設定記錄器層級(例如,在 application.properties 中),方法是使用 logging.level.<logger-name>=<level> 層級是 TRACE、DEBUG、INFO、WARN、ERROR、FATAL 或 OFF 之一。 您可以使用 來設定根記錄器 logging.level.root

下列範例顯示 application.properties 檔案中的潛在記錄設定:

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

如需有關 Spring 中記錄設定的詳細資訊,請參閱 Spring 檔中的記錄

下一步

若要深入了解 Spring 和 Azure,請繼續閱讀「Azure 上的 Spring」文件中心中的資訊。