使用 Spring Cloud Azure 保護你的 REST API

這個教學會示範如何在 Spring Boot 應用程式中啟用 REST API 保護,使用 Microsoft Entra ID。

本文使用問卷系統作為範例。 問卷系統提供下列 REST API:

  • GET /api/survey/question 用於檢視問卷。
  • POST /api/survey 用於填寫問卷。
  • GET /api/survey 用於檢視問卷結果。

在本文中,您會套用角色型訪問控制 (RBAC) 來強制執行下列需求來保護這些 API:

  • GET /api/survey/question 可供每次請求使用。
  • POST /api/survey 可用於包含已授與 SCOPE_Survey.User 範圍的存取令牌的已驗證使用者要求。
  • GET /api/survey 適用於已驗證的系統管理員使用者要求,其中包含已授與 SCOPE_Survey.Admin 範圍的存取令牌。

先決條件

這很重要

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

註冊 REST API

請依照以下步驟在 Azure 入口網站註冊您的網頁 API。

  1. 登入 Azure 入口網站。

  2. 如果您有多個租戶的存取權,請使用「目錄 + 訂閱」篩選器來選取您要在其中註冊應用程式的租戶。

  3. 找到並選擇Microsoft Entra ID。

  4. 在Manage中,選擇應用程式註冊>新註冊。

  5. 在 [名稱 ] 欄位中輸入應用程式的名稱,例如 Api-SurveyService。 您的應用程式使用者可能會看到此名稱,稍後您可以加以變更。

  6. 針對 [支援的帳戶類型],選取 [任何組織目錄中的帳戶]。

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

  8. 在應用程式 [概觀] 頁面上,尋找 [應用程式 (用戶端) 識別碼] 值,然後將其記下以供稍後使用。 您需要它來配置這個專案的 YAML 組態檔。

  9. 在 [管理] 底下,選取 [公開 API]>[新增範圍]。 透過選取 [儲存並繼續]api://{clientId},接受建議的應用程式識別碼 URI (),然後輸入下列資訊:

    • 針對 [範圍名稱],輸入 Survey.User。
    • 針對 誰可以同意,請選取 [系統管理員和使用者]。
    • 針對 管理員同意的顯示名稱,輸入 Access the survey service as a user.。
    • 針對 管理員同意描述,輸入 Allows the users to write data in survey system.。
    • 在 使用者同意顯示名稱處,輸入 Access the survey service as a user.。
    • 使用者同意描述,輸入 Allows the users to write data in survey system.。
    • 對於 [狀態],保持 [已啟用]。
    • 選取新增範圍。
  10. 重複上一個步驟以新增另一個範圍。 當您選取 [[新增範圍]時,請輸入下列資訊:

    • 針對 [範圍名稱],輸入 Survey.Admin。
    • 針對 誰可以同意,請選取 [系統管理員和使用者]。
    • 針對 管理員同意的顯示名稱,輸入 Access the survey service as a admin.。
    • 針對 管理員同意描述,輸入 Allows the users to view data in survey system.。
    • 在 使用者同意顯示名稱處,輸入 Access the survey service as a admin.。
    • 使用者同意描述,輸入 Allows the users to view data in survey system.。
    • 對於 [狀態],保持 [已啟用]。
    • 選取新增範圍。

啟用 Spring Cloud Azure Starter Microsoft Entra ID

接著,啟用 Spring Cloud Azure 的 REST API 保護。

新增安全性依賴

要安裝 Spring Cloud Azure Starter Azure Active Directory 模組,請在你的 pom.xml 檔案中新增以下相依關係:

  • Spring Cloud Azure 物料清單(BOM):

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.azure.spring</groupId>
          <artifactId>spring-cloud-azure-dependencies</artifactId>
          <version>7.4.0</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

    備註

    如果你用的是 Spring Boot 4.0.x,請把版本設 spring-cloud-azure-dependencies 為 7.4.0。

    如果你用的是 Spring Boot 3.5.x,請把版本設 spring-cloud-azure-dependencies 為 6.5.0。

    如果你使用的是 Spring Boot 3.1.x-3.5.x,記得把版本設 spring-cloud-azure-dependencies 為 5.25.0.

    如果您使用 Spring Boot 2.x,請務必將 spring-cloud-azure-dependencies 版本設定為 4.20.0。

    此材料帳單 (BOM) 應該在 <dependencyManagement> 檔案的 區段中設定。 這確保所有 Spring Cloud Azure 相依性都使用相同的版本。

    欲了解更多關於本物料清單所用版本的資訊,請參見 Spring Cloud Azure 應該使用哪個版本。

  • The Spring Cloud Azure Starter Microsoft Entra artifact:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
    </dependency>
    
  • Spring Boot Starter OAuth2 資源伺服器工件:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    

授權處理 HTTP 請求

若要保護問卷 REST API,請使用具體範圍名稱新增註釋 @PreAuthorize("hasAuthority('SCOPE_Survey.xxx')") 以啟用保護,如下列範例所示:

import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/survey")
public class SurveyController {

    private static final String QUESTION = "Which sports do you like most?";
    private final Map<LocalDateTime, String> surveys = new LinkedHashMap<>();

    @GetMapping(value = "/question", produces = MediaType.APPLICATION_JSON_VALUE)
    public String question() {
        return QUESTION;
    }

    @PostMapping
    @PreAuthorize("hasAuthority('SCOPE_Survey.User')")
    public String addAnswer(@RequestParam("answer") String answer) {
        if (StringUtils.hasText(answer)) {
            surveys.put(LocalDateTime.now(), answer);
            return "succeeded";
        }
        return "Failed";
    }

    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    @PreAuthorize("hasAuthority('SCOPE_Survey.Admin')")
    public Map<LocalDateTime, String> list() {
        return surveys;
    }
}

更新 YAML 組態,如下列範例所示:

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

備註

在 v1.0 令牌中,設定需要 API 的用戶端識別碼,而在 v2.0 令牌中,您可以在要求中使用用戶端識別碼或應用程式識別碼 URI。 您可以設定這兩者,以正確完成受眾驗證。

部署到 Azure Spring 應用程式

在本機執行 Spring Boot 應用程式之後,您可以將它移至生產環境。 Azure Spring 應用程式 讓 Spring Boot 應用程式部署到 Azure 變得簡單,無需修改程式碼。 服務會管理 Spring 應用程式的基礎結構,讓開發人員能夠專注於其程式代碼。 Azure Spring 應用程式 提供生命週期管理,包含全面的監控與診斷、組態管理、服務發現、CI/CD 整合、藍綠部署等多項功能。 欲了解更多資訊,請參閱 快速入門:將您的第一個應用程式部署至 Azure Spring 應用程式。

後續步驟