使用 Microsoft Entra ID 保护 Java Spring Boot 应用
本文演示了一个 Java Spring Boot Web 应用,该应用使用适用于 Java 的 Microsoft Entra ID Spring Boot Starter 客户端库在 Microsoft Entra ID 租户上登录用户。 它使用 OpenID 连接协议。
下图显示了应用的拓扑:
客户端应用使用适用于 Java 的 Microsoft Entra ID Spring Boot Starter 客户端库登录用户并从 Microsoft Entra ID 获取 ID 令牌。 ID 令牌证明用户使用 Microsoft Entra ID 进行身份验证,并使用户能够访问受保护的路由。
先决条件
- JDK 版本 17。 此示例是在 Java 17 的系统上开发的,但它可能与其他版本兼容。
- Maven 3
- 建议在 Visual Studio Code 中运行此示例的 Java 扩展包。
- Microsoft Entra ID 租户。 有关详细信息,请参阅 如何获取 Microsoft Entra ID 租户。
- Microsoft Entra ID 租户中的用户帐户。 此示例不适用于个人 Microsoft 帐户。 因此,如果使用个人帐户登录到Azure 门户,并且目录中没有用户帐户,则需要立即创建一个。
- Visual Studio Code
- 用于 Visual Studio Code 的 Azure 工具
建议
- 一些熟悉 Spring Framework
- 一些熟悉 Linux/OSX 终端或 Windows PowerShell
- 用于检查令牌的 jwt.ms。
- 用于监视网络活动和故障排除的 Fiddler 。
- 按照 Microsoft Entra ID 博客了解最新开发的最新进展。
设置示例
以下部分演示如何设置示例应用程序。
克隆或下载示例存储库
若要克隆示例,请打开 Bash 窗口并使用以下命令:
git clone https://github.com/Azure-Samples/ms-identity-java-spring-tutorial.git
cd ms-identity-java-spring-tutorial
cd 1-Authentication/sign-in
或者,导航到 ms-identity-java-spring-tutorial 存储库,然后将其下载为 .zip 文件并将其解压缩到硬盘驱动器。
重要
为了避免 Windows 上的路径长度限制,建议克隆到驱动器根附近的目录中。
向 Microsoft Entra ID 租户注册示例应用程序
此示例中有一个项目。 若要在Azure 门户上注册应用,可以按照手动配置步骤或使用 PowerShell 脚本。 该脚本执行以下任务:
- 创建 Microsoft Entra ID 应用程序和相关对象,例如密码、权限和依赖项。
- 修改项目配置文件。
- 默认情况下,设置仅适用于组织目录中的帐户的应用程序。
使用以下步骤运行 PowerShell 脚本:
在 Windows 上,打开 PowerShell 并导航到克隆目录的根目录。
使用以下命令设置 PowerShell 的执行策略:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
使用以下命令运行配置脚本:
cd .\AppCreationScripts\ .\Configure.ps1
注意
应用创建脚本中介绍了运行脚本的其他方法。 这些脚本还提供了自动化应用程序注册、配置和删除指南,有助于 CI/CD 方案。
配置应用(java-spring-webapp-auth)以使用应用注册
使用以下步骤配置应用:
注意
在以下步骤中, ClientID
与 Application ID
或 AppId
相同。
在 IDE 中打开项目。
打开 src\main\resources\application.yml 文件。
找到占位符
Enter_Your_Tenant_ID_Here
,并将现有值替换为 Microsoft Entra 租户 ID。找到占位符
Enter_Your_Client_ID_Here
,并将现有值替换为从Azure 门户复制的应用程序 ID 或java-spring-webapp-auth
clientId
应用。找到占位符
Enter_Your_Client_Secret_Here
,并将现有值替换为在创建java-spring-webapp-auth
从Azure 门户复制期间保存的值。
运行示例
以下部分介绍如何将示例部署到 Azure Spring Apps。
先决条件
如果你是首次在目标订阅中部署 Azure Spring Apps 企业计划实例,请参阅 Azure 市场中的企业计划的要求部分。
适用于 Azure Spring Apps 的 Maven 插件。 如果 Maven 不是首选开发工具,请参阅以下使用其他工具的类似教程:
准备 Spring 项目
使用以下步骤来准备项目:
使用以下 Maven 命令生成项目:
mvn clean package
使用以下命令在本地运行示例项目:
mvn spring-boot:run
配置 Maven 插件
在项目的根目录中运行以下命令,使用适用于 Azure Spring Apps 的 Maven 插件配置应用:
mvn com.microsoft.azure:azure-spring-apps-maven-plugin:1.19.0:config
以下列表描述了命令交互:
- OAuth2 登录名:需要根据 OAuth2 协议授权登录到 Azure。
- 选择订阅:选择要在其中创建 Azure Spring Apps 实例的订阅列表编号,该实例默认为列表中的第一个订阅。 如果要使用默认数字,请按 Enter。
- 输入 Azure Spring Apps 名称:输入要创建的 Spring 应用实例的名称。 如果要使用默认名称,请按 Enter。
- 输入资源组名称:输入要在其中创建 Spring 应用实例的资源组的名称。 如果要使用默认名称,请按 Enter。
- Sku:选择要用于 Spring 应用实例的 SKU。 如果要使用默认数字,请按 Enter。
- 输入应用名称(演示):提供应用名称。 如果要使用默认项目项目 ID,请按 Enter。
- 运行时:选择要用于 Spring 应用实例的运行时。 在这种情况下,应使用默认数字,请按 Enter。
- 公开此应用的公共访问权限 (boot-for-azure):按 y。
- 确认保存上述所有配置:按 y。 如果按 n,则配置不会保存在 .pom 文件中。
以下示例显示了部署过程的输出:
Summary of properties:
Subscription id : 12345678-1234-1234-1234-123456789101
Resource group name : rg-ms-identity-spring-boot-webapp
Azure Spring Apps name : cluster-ms-identity-spring-boot-webapp
Runtime Java version : Java 11
Region : eastus
Sku : Standard
App name : ms-identity-spring-boot-webapp
Public access : true
Instance count/max replicas : 1
CPU count : 1
Memory size(GB) : 2
Confirm to save all the above configurations (Y/n):
[INFO] Configurations are saved to: /home/user/ms-identity-java-spring-tutorial/1-Authentication/sign-in/pom. xml
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:57 min
[INFO] Finished at: 2024-02-14T13:50:44Z
[INFO] ------------------------------------------------------------------------
确认选择后,该插件会将所需的插件元素和设置添加到项目的 pom.xml 文件中,以将应用配置为在 Azure Spring Apps 中运行。
pom.xml文件的相关部分应类似于以下示例:
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-apps-maven-plugin</artifactId>
<version>1.19.0</version>
<configuration>
<subscriptionId>12345678-1234-1234-1234-123456789101</subscriptionId>
<resourceGroup>rg-ms-identity-spring-boot-webapp</resourceGroup>
<clusterName>cluster-ms-identity-spring-boot-webapp</clusterName>
<region>eastus</region>
<sku>Standard</sku>
<appName>ms-identity-spring-boot-webapp</appName>
<isPublic>true</isPublic>
<deployment>
<cpu>1</cpu>
<memoryInGB>2</memoryInGB>
<instanceCount>1</instanceCount>
<runtimeVersion>Java 11</runtimeVersion>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.jar</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
可以直接在 pom.xml 文件中修改 Azure Spring Apps 的配置。 下表列出了一些常见配置:
properties | 必选 | 说明 |
---|---|---|
subscriptionId |
false | 订阅的 ID。 |
resourceGroup |
是 | Azure Spring Apps 实例的 Azure 资源组。 |
clusterName |
是 | Azure Spring Apps 群集名称。 如果使用已部署 Azure Spring Apps 实例的订阅和资源组,也可以使用此现有群集部署到该群集。 |
appName |
是 | Azure Spring Apps 中的应用的名称。 |
region |
false | 要在其中托管 Azure Spring Apps 实例的区域。 默认值为 eastus 。 有关有效区域,请参阅 支持的区域。 |
sku |
false | Azure Spring Apps 实例的定价层。 默认值 Basic 仅适用于开发和测试环境。 |
runtime |
false | 运行时环境配置。 有关详细信息,请参阅配置详细信息。 |
deployment |
false | 部署配置。 有关详细信息,请参阅配置详细信息。 |
有关配置的完整列表,请参阅插件参考文档。 所有 Azure Maven 插件共享一组常见的配置。 有关这些配置,请参阅 常见配置。 有关特定于 Azure Spring Apps 的配置,请参阅 Azure Spring Apps:配置详细信息。
请务必保存保留这些 clusterName
值, appName
供以后使用。
准备应用进行部署
将应用程序部署到 Azure Spring Apps 时,重定向 URL 将更改为 Azure Spring Apps 中已部署的应用实例的重定向 URL。 使用以下步骤更改application.yml文件中的这些设置:
导航到应用的 src\main\resources\application.yml 文件并更改已部署应用的域名的值
post-logout-redirect-uri
,如以下示例所示。 例如,如果在cluster-ms-identity-spring-boot-webapp
上一步中选择了 Azure Spring Apps 实例和ms-identity-spring-boot-webapp
应用名称,则现在必须用于https://cluster-ms-identity-spring-boot-webapp-ms-identity-spring-boot-webapp.azuremicroservices.io
post-logout-redirect-uri
该值。post-logout-redirect-uri: https://<cluster-name>-<app-name>.azuremicroservices.io
保存此文件后,使用以下命令重新生成应用:
mvn clean package
重要
应用程序的application.yml文件当前在参数中client-secret
保存客户端机密的值。 最好将此值保存在此文件中。 如果将其提交到 Git 存储库,则也可能面临风险。
作为额外的安全步骤,可以将此值存储在 Azure 密钥库中,并从密钥库加载机密,使其在应用程序中可用。
更新 Microsoft Entra ID 应用注册
由于重定向 URI 更改为 Azure Spring Apps 上已部署的应用,因此还需要在 Microsoft Entra ID 应用注册中更改重定向 URI。 若要进行此更改,请使用以下步骤:
导航到面向开发人员的 Microsoft 标识平台应用注册页。
使用搜索框搜索应用注册 ,例如
java-servlet-webapp-authentication
。通过选择应用名称打开应用注册。
从菜单中选择“身份验证”。
在“Web - 重定向 URI”部分中,选择“添加 URI”。
填写应用的 URI,追加
/login/oauth2/code/
- 例如。https://<cluster-name>-<app-name>.azuremicroservices.io/login/oauth2/code/
选择“保存”。
部署应用
使用以下命令部署应用:
mvn azure-spring-apps:deploy
以下列表描述了命令交互:
- OAuth2 登录名:需要根据 OAuth2 协议授权登录到 Azure。
执行命令后,你会从以下日志消息中看到部署已成功:
[INFO] Deployment(default) is successfully created
[INFO] Starting Spring App after deploying artifacts...
[INFO] Deployment Status: Running
[INFO] InstanceName:demo-default-x-xxxxxxxxxx-xxxxx Status:Running Reason:null DiscoverStatus:UNREGISTERED
[INFO] InstanceName:demo-default-x-xxxxxxxxx-xxxxx Status:Terminating Reason:null DiscoverStatus:UNREGISTERED
[INFO] Getting public url of app(demo)...
[INFO] Application url: https://<your-Azure-Spring-Apps-instance-name>-demo.azuremicroservices.io
验证应用
部署完成后,使用输出应用程序 URL 来访问应用程序。 按以下步骤检查应用程序的日志,以调查任何部署问题:
从“部署”部分的“输出”页访问输出应用程序 URL。
在 Azure Spring Apps 实例“概述”页面的导航窗格中,选择“日志”以检查应用的日志。
探索示例
使用以下步骤浏览示例:
- 请注意屏幕中心显示的已登录或注销状态。
- 选择角落中的上下文敏感按钮。 首次运行应用时,此按钮将 读取登录 。 或者,选择 令牌详细信息。 由于此页面受保护且需要身份验证,因此会自动重定向到登录页。
- 在下一页上,按照说明使用 Microsoft Entra ID 租户中的帐户登录。
- 在同意屏幕上,请注意请求的范围。
- 成功完成登录流后,应重定向到主页(显示 登录状态 )或 令牌详细信息 页,具体取决于哪个按钮触发了登录流。
- 请注意,上下文相关的按钮现在显示 “注销 ”并显示用户名。
- 如果位于主页上,请选择“ID 令牌详细信息”以查看一些 ID 令牌解码的声明。
- 使用角落中的按钮注销。状态页反映新状态。
关于代码
此示例演示如何使用 适用于 Java 的 Microsoft Entra ID Spring Boot Starter 客户端库将用户登录到 Microsoft Entra ID 租户。 此示例还使用 Spring Oauth2 客户端和 Spring Web 启动器。 此示例使用从 Microsoft Entra ID 获取的 ID 令牌中的声明来显示已登录用户的详细信息。
目录
下表显示了示例项目文件夹的内容:
文件/文件夹 | 说明 |
---|---|
AppCreationScripts/ | 用于自动配置 Microsoft Entra ID 应用注册的脚本。 |
pom.xml | 应用程序依赖项。 |
src/main/resources/templates/ | 用于 UI 的 Thymeleaf 模板。 |
src/main/resources/application.yml | 应用程序和 Microsoft Entra ID 启动启动程序库配置。 |
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ | 此目录包含应用程序入口点、控制器和配置类。 |
.../MsIdentitySpringBootWebappApplication.java | Main 类。 |
.../SampleController.java | 具有终结点映射的控制器。 |
.../SecurityConfig.java | 安全配置 - 例如,需要身份验证的路由。 |
.../Utilities.java | 实用工具类 - 例如,筛选器 ID 令牌声明。 |
CHANGELOG.md | 示例更改列表。 |
CONTRIBUTING.md | 参与示例的指南。 |
LICEN标准版 | 示例的许可证。 |
ID 令牌声明
为了提取令牌详细信息,应用在请求映射中使用 Spring Security 和AuthenticationPrincipal
OidcUser
对象,如以下示例所示。 有关此应用如何使用 ID 令牌声明的完整详细信息,请参阅示例控制器。
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 的 Microsoft Entra ID Spring Boot Starter 客户端库自动配置的 Microsoft Entra ID 登录终结点发出请求,如以下示例所示:
<a class="btn btn-success" href="/oauth2/authorization/azure">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>
使用 AADWebSecurityConfigurerAdapter 保护路由
默认情况下,应用会 保护 ID 令牌详细信息 页,以便只有已登录的用户才能访问它。 应用通过使用app.protect.authenticated
application.yml文件中的属性来配置这些路由。 若要配置应用的特定要求,请将 AadWebApplicationHttpSecurityConfigurer#aadWebApplication
该方法应用于 HttpSecurity
实例。 有关示例,请参阅此应用的 SecurityConfig 类,如以下代码所示:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Value("${app.protect.authenticated}")
private String[] allowedOrigins;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
.and()
.authorizeHttpRequests(auth -> auth
.requestMatchers(allowedOrigins).authenticated()
.anyRequest().permitAll()
);
// @formatter:on
return http.build();
}
@Bean
@RequestScope
public ServletUriComponentsBuilder urlBuilder() {
return ServletUriComponentsBuilder.fromCurrentRequest();
}
}
详细信息
- Microsoft 标识平台 (面向开发人员的 Microsoft Entra ID)
- Microsoft 身份验证库 (MSAL) 概述
- 快速入门:将应用程序注册到 Microsoft 标识平台
- 快速入门:配置客户端应用程序以访问 Web API
- 了解 Microsoft Entra ID 应用程序同意体验
- 了解用户同意和管理员同意
- Microsoft Entra ID 中的应用程序和服务主体对象
- 国家云
- MSAL 代码示例
- 适用于 Java 的 Microsoft Entra ID Spring Boot Starter 客户端库
- 适用于 Java 的 Microsoft 身份验证库 (MSAL4J)
- MSAL4J Wiki
- ID 令牌
- Microsoft 标识平台中的访问令牌
有关 OAuth 2.0 协议在此方案中的工作方式和其他方案的详细信息,请参阅 Microsoft Entra ID 的身份验证方案。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈