使用 Azure Active Directory B2C 保护 Java Spring Boot 应用
本文演示了一个 Java Spring Boot Web 应用,该应用使用适用于 Java 的 Azure AD B2C Spring Boot Starter 客户端库在 Azure Active Directory B2C 租户上登录用户。 它使用 OpenID Connect 协议。
下图显示了应用的拓扑:
客户端应用使用适用于 Java 的 Azure AD B2C Spring Boot Starter 客户端库登录用户并从 Azure AD B2C 获取 ID 令牌。 ID 令牌证明用户使用 Azure AD B2C 进行身份验证,并使用户能够访问受保护的路由。
先决条件
- JDK 版本 15。 此示例是在 Java 15 系统上开发的,但它可能与其他版本兼容。
- Maven 3
- 建议在 Visual Studio Code 中运行此示例的 Java 扩展包。
- Azure AD B2C 租户。 有关详细信息,请参阅 教程:创建 Azure Active Directory B2C 租户
- 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-msal-java-samples.git
cd 4-spring-web-app/1-Authentication/sign-in-b2c
或者,导航到 ms-identity-msal-java-samples 存储库,然后将其下载为 .zip 文件并将其提取到硬盘驱动器。
重要
若要避免 Windows 上的文件路径长度限制,请将存储库克隆或提取到硬盘驱动器根附近的目录中。
此示例附带了预注册的应用程序,用于演示目的。 若要使用自己的 Azure AD B2C 租户和应用程序,请在Azure 门户中注册和配置该应用程序。 有关详细信息,请参阅“ 注册应用 ”部分。 否则,请继续执行“运行示例”部分中的步骤。
选择要在其中创建应用程序的 Azure AD B2C 租户
若要选择租户,请使用以下步骤:
登录到 Azure 门户。
如果帐户存在于多个 Azure AD B2C 租户中,请选择Azure 门户角的配置文件,然后选择“切换目录”以将会话更改为所需的 Azure AD B2C 租户。
创建用户流和自定义策略
若要创建常见的用户流,例如注册、登录、配置文件编辑和密码重置,请参阅 教程:在 Azure Active Directory B2C 中创建用户流。
还应考虑在 Azure Active Directory B2C 中创建自定义策略。 但是,此任务超出了本教程的范围。 有关详细信息,请参阅 Azure AD B2C 自定义策略概述。
添加外部标识提供者
请参阅 教程:将标识提供者添加到 Azure Active Directory B2C 中的应用程序。
注册应用(java-spring-webapp-auth-b2c)
若要注册应用,请使用以下步骤:
导航到Azure 门户并选择 Azure AD B2C。
在导航窗格中选择 “应用注册 ”,然后选择“ 新建注册”。
在 显示的“注册应用程序”页 中,输入以下应用程序注册信息:
- 在“ 名称 ”部分中,输入一个有意义的应用程序名称,以便向应用的用户显示,例如
java-spring-webapp-auth-b2c
。 - 在“支持的帐户类型”下,选择“任何标识提供者或组织目录中的帐户(用于通过用户流对用户进行身份验证)” 。
- 在“重定向 URI”(可选)部分中,在组合框中选择“Web”,然后输入以下重定向 URI:
http://localhost:8080/login/oauth2/code/
- 在“ 名称 ”部分中,输入一个有意义的应用程序名称,以便向应用的用户显示,例如
选择“注册”以创建应用程序。
在应用的注册页上,查找并复制 应用程序(客户端)ID 值以供以后使用。 在应用的配置文件或文件中使用此值。
选择“保存”以保存更改。
在应用的注册页上,选择 导航窗格中的“证书和机密 ”窗格,打开页面以生成机密并上传证书。
在“客户端密码”部分中,选择“新建客户端密码” 。
键入说明 - 例如应用 机密。
根据安全问题选择其中一个可用持续时间 ,例如, 在 2 年内。
选择 添加 。 将显示生成的值。
复制并保存生成的值,以便在后续步骤中使用。 代码的配置文件需要此值。 此值不会再次显示,不能通过任何其他方式检索该值。 因此,在导航到任何其他屏幕或窗格之前,请务必将其从Azure 门户保存。
配置应用(java-spring-webapp-auth-b2c)以使用应用注册
使用以下步骤配置应用:
注意
在以下步骤中, ClientID
与 Application ID
或 AppId
相同。
在 IDE 中打开项目。
打开 src/main/resources/application.yml 文件。
找到该
client-id
属性,并将现有值替换为应用程序 ID 或clientId
java-spring-webapp-auth-b2c
Azure 门户中的应用程序。找到该属性,并将
client-secret
现有值替换为在从Azure 门户创建java-spring-webapp-auth-b2c
应用程序期间保存的值。找到该
base-uri
属性,并将值的两个实例fabrikamb2c
替换为在Azure 门户中创建java-spring-webapp-auth-b2c
应用程序的 Azure AD B2C 租户的名称。找到该
sign-up-or-sign-in
属性,并将其替换为在 azure AD B2C 租户中创建的注册/登录用户流策略的名称,在该租户java-spring-webapp-auth-b2c
中创建应用程序Azure 门户。找到该
profile-edit
属性,并将其替换为在 azure AD B2C 租户java-spring-webapp-auth-b2c
中创建的应用程序在Azure 门户中创建的应用程序的密码重置用户流策略的名称。找到该
password-reset
属性,并将其替换为在 azure AD B2C 租户中创建的编辑配置文件用户流策略的名称,在该租户java-spring-webapp-auth-b2c
中创建Azure 门户中的应用程序。打开 src/main/resources/templates/navbar.html 文件。
查找对
b2c_1_susi
流和b2c_1_edit_profile
流的引用,并将其替换为你的sign-up-sign-in
流和profile-edit
用户流。
运行示例
以下部分介绍如何将示例部署到 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-msal-java-samples/4-spring-web-app/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 实例“概述”页面的导航窗格中,选择“日志”以检查应用的日志。
探索示例
使用以下步骤浏览示例:
- 请注意屏幕中心显示的已登录或注销状态。
- 选择角落中的上下文敏感按钮。 首次运行应用时,此按钮将 读取登录 。 或者,选择令牌 详细信息的链接。 由于此页面受保护且需要身份验证,因此会自动重定向到登录页。
- 在下一页上,按照说明使用所选标识提供者的帐户登录。 还可以选择使用电子邮件地址在 B2C 租户上注册或登录到本地帐户。
- 成功完成登录流后,应重定向到主页(显示 登录状态 )或 令牌详细信息 页,具体取决于哪个按钮触发了登录流。
- 请注意,上下文敏感按钮现在显示 “注销 ”并显示用户名。
- 如果位于主页上,请选择“ID 令牌详细信息”以查看一些 ID 令牌解码的声明。
- 编辑个人资料。 选择 “编辑配置文件 ”以更改显示名称、居住地和职业等详细信息。
- 使用角落中的按钮注销。状态页反映新状态。
关于代码
此示例演示如何使用 适用于 Java 的 Azure AD B2C Spring Boot Starter 客户端库将用户登录到 Azure AD B2C 租户。 此示例还使用 Spring Oauth2 客户端和 Spring Web 启动器。 此示例使用从 Azure AD B2C 获取的 ID 令牌中的声明来显示已登录用户的详细信息。
目录
下表显示了示例项目文件夹的内容:
文件/文件夹 | 说明 |
---|---|
pom.xml | 应用程序依赖项。 |
src/main/resources/templates/ | 用于 UI 的 Thymeleaf 模板。 |
src/main/resources/application.yml | 应用程序和Microsoft Entra Boot Starter 库配置。 |
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ | 此目录包含应用程序入口点、控制器和配置类。 |
.../MsIdentitySpringBootWebappApplication.java | Main 类。 |
.../SampleController.java | 具有终结点映射的控制器。 |
.../SecurityConfig.java | 安全配置 - 例如,需要身份验证的路由。 |
.../Utilities.java | 实用工具类 - 例如,筛选器 ID 令牌声明。 |
CHANGELOG.md | 示例更改列表。 |
CONTRIBUTING.md | 参与示例的指南。 |
许可证 | 示例的许可证。 |
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 的 Azure AD B2C Spring Boot Starter 客户端库自动配置的 Azure AD B2C 登录终结点发出请求,如以下示例所示:
<a class="btn btn-success" href="/oauth2/authorization/{your-sign-up-sign-in-user-flow}">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>
使用 WebSecurityConfigurerAdapter 保护路由
默认情况下,应用会 保护 ID 令牌详细信息 页,以便只有已登录的用户才能访问它。 应用从app.protect.authenticated
application.yml文件中的属性配置这些路由。 若要配置应用的特定要求,可以在其中一个类中扩展 WebSecurityConfigurerAdapter
。 有关示例,请参阅此应用的 SecurityConfig 类,如以下代码所示:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${app.protect.authenticated}")
private String[] protectedRoutes;
private final AADB2COidcLoginConfigurer configurer;
public SecurityConfig(AADB2COidcLoginConfigurer configurer) {
this.configurer = configurer;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.authorizeRequests()
.antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details)
.antMatchers("/**").permitAll() // allow all other routes.
.and()
.apply(configurer)
;
// @formatter:off
}
}
详细信息
- Microsoft 标识平台(面向开发人员的 Microsoft Entra ID)
- Microsoft身份验证库(MSAL)概述
- 快速入门:将应用程序注册到 Microsoft 标识平台
- 快速入门:配置客户端应用程序以访问 Web API
- 了解 Microsoft Entra ID 应用程序许可体验
- 了解用户同意和管理员同意
- Microsoft Entra ID 中的应用程序和服务主体对象
- 国家云
- MSAL 代码示例
- Microsoft适用于 Java 的 Entra ID Spring Boot Starter 客户端库
- 适用于 Java 的 Azure Active Directory B2C Spring Boot Starter 客户端库
- Microsoft Java 身份验证库 (MSAL4J)
- MSAL4J Wiki
- ID 令牌
- Microsoft 标识平台中的访问令牌
有关 OAuth 2.0 协议在此方案中的工作方式和其他方案的详细信息,请参阅 Microsoft Entra ID 的身份验证方案。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈