本教程介绍如何在 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 Web 、OAuth2 Resource Server 和Microsoft Entra ID 依赖项,然后选择Java版本 8 或更高版本。
重要
完成本文中的步骤需要 Spring Boot 2.5 或更高版本。
注册 REST API
使用以下步骤在 Azure 门户中注册 Web API。
登录到 Azure 门户。
如果您有权访问多个租户,请使用目录和订阅筛选器(
)选择要注册应用程序的租户。查找并选择 Microsoft Entra ID。
在 Manage 下,选择 应用注册>新注册。
在 名称 字段中输入应用程序的名称,例如
Api-SurveyService。 应用的用户可能会看到此名称,稍后可以对其进行更改。在“支持的帐户类型”下,选择“任何组织目录中的帐户” 。
选择“注册”以创建应用程序。
在应用的“概述”页上,找到“应用程序(客户端) ID”值,然后记下该值以供后续使用 。 需要它来配置此项目的 YAML 配置文件。
在管理下,选择公开 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.。 - 对于“状态”,保留“启用”。
- 选择添加作用域。
- 对于范围名称,请输入
重复上一步以添加另一个作用域。 选择“添加范围”时,请输入以下信息:
- 对于范围名称,请输入
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 示例