使用 Spring Cloud Azure保护 REST API

本教程介绍如何在 Spring Boot 应用程序中使用 Microsoft Entra ID 启用 REST API 保护。

本文以调查系统为例。 调查系统提供以下 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 范围的访问令牌。

先决条件

  • Azure订阅 - 免费创建一个订阅
  • Java开发工具包(JDK)版本 8 或更高版本。
  • Apache Maven
  • Azure CLI
  • Microsoft Entra实例。 有关创建一个租户的说明,请参阅 Quickstart:在 Microsoft Entra ID
  • Spring Boot 应用程序。 如果没有,请使用 Spring Initializr 创建一个 Maven 项目。 请务必选择 Maven Project,并在 Dependencies 添加 Spring WebOAuth2 Resource ServerMicrosoft Entra ID 依赖项,然后选择Java版本 8 或更高版本。

重要

完成本文中的步骤需要 Spring Boot 2.5 或更高版本。

注册 REST API

使用以下步骤在 Azure 门户中注册 Web API。

  1. 登录到 Azure 门户

  2. 如果您有权访问多个租户,请使用目录和订阅筛选器)选择要注册应用程序的租户。

  3. 查找并选择 Microsoft Entra ID

  4. Manage 下,选择 应用注册>新注册

  5. 名称 字段中输入应用程序的名称,例如 Api-SurveyService。 应用的用户可能会看到此名称,稍后可以对其进行更改。

  6. 在“支持的帐户类型”下,选择“任何组织目录中的帐户” 。

  7. 选择“注册”以创建应用程序。

  8. 在应用的“概述”页上,找到“应用程序(客户端) ID”值,然后记下该值以供后续使用 。 需要它来配置此项目的 YAML 配置文件。

  9. 管理下,选择公开 API>添加范围。 通过选择“保存并继续”来接受建议的应用程序 ID URI (api://{clientId}),然后输入以下信息:

    • 对于范围名称,请输入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.2.0</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

    注意

    如果使用 Spring Boot 4.0.x,请确保将 spring-cloud-azure-dependencies 版本设置为 7.2.0

    如果使用 Spring Boot 3.5.x,请确保将 spring-cloud-azure-dependencies 版本设置为 6.2.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

    应在 <dependencyManagement> 文件的 部分中配置此材料清单(BOM)。 这可确保所有 Spring Cloud Azure依赖项都使用相同的版本。

    有关用于此 BOM 的版本的详细信息,请参阅 我应该使用哪个版本的 Spring Cloud Azure

  • Spring Cloud Azure Starter Microsoft Entra 构件:

    <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 的客户端 ID,而在 v2.0 令牌中,可以在请求中使用客户端 ID 或应用程序 ID URI。 可以同时配置这两项以正确完成受众验证。

部署到Azure Spring Apps

在本地运行 Spring Boot 应用程序后,可以将其移动到生产环境。 Azure Spring Apps可以轻松地将 Spring Boot 应用程序部署到Azure,而无需更改任何代码。 该服务管理 Spring 应用程序的基础结构,以便开发人员可以专注于其代码。 Azure Spring Apps使用全面的监视和诊断、配置管理、服务发现、CI/CD 集成、蓝绿部署等提供生命周期管理。 有关详细信息,请参阅 Quickstart:将第一个应用程序部署到 Azure Spring Apps

后续步骤

适用于 Spring 开发人员的 AzureSpring Cloud Microsoft Entra ID 示例