通过 OpenID Connect 使用 Microsoft Entra ID 确保 Quarkus 应用程序的安全
本文演示如何使用 OpenID Connect (OIDC) 确保 Red Hat Quarkus 应用程序与 Microsoft Entra ID 的安全。
在本文中,学习如何:
- 使用 Microsoft Entra ID 设置 OpenID Connect 提供程序。
- 使用 OpenID Connect 保护 Quarkus 应用。
- 运行并测试 Quarkus 应用。
先决条件
- Azure 订阅。 如果还没有 Azure 订阅,可以在开始前创建一个免费帐户。
- 至少具有云应用程序管理员 Microsoft Entra 角色的 Azure 标识。 有关详细信息,请参阅列出 Microsoft Entra 角色分配和 Microsoft Entra 内置角色。
- 一个 Microsoft Entra 租户。 如果还没有租户,请参阅快速入门:设置租户。
- 一台安装了类似于 Unix 的操作系统(例如 Ubuntu、macOS 或适用于 Linux 的 Windows 子系统)的本地计算机。
- Git。
- 版本为 21 或更高的 Java SE 实现,例如 OpenJDK 的 Microsoft 版本。
- Maven,3.9.3 或更高版本。
使用 Microsoft Entra ID 设置 OpenID Connect 提供程序
在本部分中,将使用 Microsoft Entra ID 设置 OpenID Connect 提供商,以便与 Quarkus 应用一起使用。 在后面的部分中,将使用 OpenID Connect 配置 Quarkus 应用,以便在 Microsoft Entra 租户中对用户进行身份验证和授权。
在 Microsoft Entra 租户中创建用户
首先,按照如何创建、邀请和删除用户中的步骤在 Microsoft Entra 租户中创建两个用户。 只用参阅创建新用户部分。 在阅读本文时使用以下说明,然后在 Microsoft Entra 租户中创建用户后返回到本文。
要创建一个用户作为应用中的“管理员”,请执行以下步骤:
要创建一个用户作为应用中的“用户”,请重复上述步骤,但要使用以下值:
- 在用户主体名称中,输入 user。
- 在显示名称中,输入 User。
在 Microsoft Entra ID 中注册应用程序
接下来,按照快速入门:向 Microsoft 标识平台注册应用程序中的步骤注册应用程序。 阅读本文时请遵循以下说明,然后在注册并配置应用程序后返回本文。
- 在到达注册应用程序部分时,请按照以下步骤操作:
- 对于“支持的帐户类型”,选择“仅此组织目录中的帐户(仅默认目录 - 单租户)”。
- 注册完成后,保存“应用程序(客户端)ID”和“目录(租户)ID”值,以便以后在应用配置中使用。
- 到达“添加重定向 URI”部分时,现在跳过以下步骤。 稍后在本文中,在本地运行和测试示例应用时将添加重定向 URI。
- 在到达“添加凭据”部分时,选择“添加客户端机密”选项卡。
- 在添加客户端密码时,请记下“客户端机密”值,以便稍后在应用配置中使用。
向应用程序添加应用角色
然后,按照为应用程序添加应用角色并在令牌中接收中的步骤为应用程序添加应用角色。 只需要部分为应用程序声明角色和将用户和组分配给 Microsoft Entra 角色。 阅读本文时请遵循以下说明,然后在声明应用程序的角色后返回本文。
在为应用程序声明角色部分中,使用应用角色 UI 为管理员和一般用户创建角色。
在访问将用户和组分配给 Microsoft Entra 角色部分时,请执行以下步骤:
请不要遵循将应用角色添加到应用程序并在令牌中接收它们中的任何其他步骤。
使用 OpenID Connect 保护 Quarkus 应用
在本部分中,将使用 OpenID Connect 保护 Quarkus 应用,该应用会对 Microsoft Entra 租户中的用户进行身份验证和授权。 你还将学习如何使用基于角色的访问控制 (RBAC) 授予用户对应用某些部分的访问权限。
本快速入门的示例 Quarkus 应用位于 GitHub 上的 quarkus-azure 存储库中,并在 entra-id-quarkus 目录中。
启用身份验证和授权以保护应用
应用在 WelcomePage.java 中定义了一个欢迎页面资源,如下面的示例代码所示。 未经身份验证的用户可以访问此页面。 欢迎页面的根路径位于 /
。
@Path("/")
public class WelcomePage {
private final Template welcome;
public WelcomePage(Template welcome) {
this.welcome = requireNonNull(welcome, "welcome page is required");
}
@GET
@Produces(MediaType.TEXT_HTML)
public TemplateInstance get() {
return welcome.instance();
}
}
从欢迎页面中,用户可以登录应用并访问配置文件页面。 欢迎页面包含以用户或管理员身份登录的链接。链接分别位于 /profile/user
和 /profile/admin
。 欢迎页面 UI 定义在 welcome.qute.html 中,如下例所示:
<html>
<head>
<meta charset="UTF-8">
<title>Greeting</title>
</head>
<body>
<h1>Hello, welcome to Quarkus and Microsoft Entra ID integration!</h1>
<h1>
<a href="/profile/user">Sign in as user</a>
</h1>
<h1>
<a href="/profile/admin">Sign in as admin</a>
</h1>
</body>
</html>
/profile/user
和 /profile/admin
链接都指向配置文件页面资源,该资源在 ProfilePage.java 中定义,如下面的示例代码所示。 只有使用 @RolesAllowed("**")
包中的 jakarta.annotation.security.RolesAllowed
注释经过身份验证的用户才能访问此页面。 @RolesAllowed("**")
批注指定只有经过身份验证的用户才能访问 /profile
路径。
@Path("/profile")
@RolesAllowed("**")
public class ProfilePage {
private final Template profile;
@Inject
SecurityIdentity identity;
@Inject
JsonWebToken accessToken;
public ProfilePage(Template profile) {
this.profile = requireNonNull(profile, "profile page is required");
}
@Path("/admin")
@GET
@Produces(MediaType.TEXT_HTML)
@RolesAllowed("admin")
public TemplateInstance getAdmin() {
return getProfile();
}
@Path("/user")
@GET
@Produces(MediaType.TEXT_HTML)
@RolesAllowed({"user","admin"})
public TemplateInstance getUser() {
return getProfile();
}
private TemplateInstance getProfile() {
return profile
.data("name", identity.getPrincipal().getName())
.data("roles", identity.getRoles())
.data("scopes", accessToken.getClaim("scp"));
}
}
配置文件页面资源使用 @RolesAllowed
批注来启用 RBAC。 @RolesAllowed
批注的参数指定只有具有 admin
角色的用户才能访问 /profile/admin
路径,而具有 user
或 admin
角色的用户才能访问 /profile/user
路径。
终结点 /profile/admin
和 /profile/user
返回配置文件页面。 配置文件页面 UI 在 profile.qute.html 中定义,如下例所示。 此页面显示用户的名称、角色和范围。 配置文件页面在 /logout
处还有一个退出链接,该链接会将用户重定向到 OIDC 提供商以退出。配置文件页面是使用 Qute 模板引擎编写的。 请注意页面中 {}
表达式的使用。 这些表达式利用了通过 TemplateInstance
方法传递给 data()
的值。 有关 Qute 的详细信息,请参阅 Qute 模板化引擎。
<html>
<head>
<meta charset="UTF-8">
<title>Profile</title>
</head>
<body>
<h1>Hello, {name}</h1>
<h2>Roles</h2>
<ul>
{#if roles}
{#for role in roles}
<li>{role}</li>
{/for}
{#else}
<li>No roles found!</li>
{/if}
</ul>
<h2>Scopes</h2>
<p>
{scopes}
</p>
<h1>
<b><a href="/logout">Sign out</a></b>
</h1>
</body>
</html>
注销后,用户将被重定向到欢迎页面并可以再次登录。
运行并测试 Quarkus 应用
在本部分中,将运行并测试 Quarkus 应用,以了解它如何与 Microsoft Entra ID 作为 OpenID Connect 提供程序配合使用。
向应用注册中添加重定向 URI
若要在本地成功运行和测试应用,需要向应用注册添加重定向 URI。 按照快速入门:将应用程序注册到 Microsoft 标识平台的添加重定向 URI 部分中的说明执行操作,并使用以下值:
- 在“配置平台”中,选择“Web”。
- 对于“重定向 URI”,请输入 。
准备示例
按照以下步骤准备示例 Quarkus 应用:
使用以下命令从 GitHub 克隆示例 Quarkus 应用,并导航到 entra-id-quarkus 目录:
git clone https://github.com/Azure-Samples/quarkus-azure cd quarkus-azure/entra-id-quarkus git checkout 2024-09-26
如果看到有关处于拆离的 HEAD 状态的消息,可以放心忽略此消息。 由于本文不需要任何提交,因此拆离的 HEAD 状态是合适的。
使用以下命令来定义以下环境变量以及之前记下的值:
export QUARKUS_OIDC_CLIENT_ID=<application/client-ID> export QUARKUS_OIDC_CREDENTIALS_SECRET=<client-secret> export QUARKUS_OIDC_AUTH_SERVER_URL=https://login.microsoftonline.com/<directory/tenant-ID>/v2.0
这些环境变量为 Quarkus 中内置的 OpenID Connect 支持提供了值。
application.properties
中对应的属性如下例所示。quarkus.oidc.client-id= quarkus.oidc.credentials.secret= quarkus.oidc.auth-server-url=
如果
application.properties
中某个属性的值为空,则Quarkus 会将属性名称转换为环境变量并从环境中读取该值。 有关命名转换的详细信息,请参阅 MicroProfile 配置规范。
运行 Quarkus 应用
可以在不同的模式下运行 Quarkus 应用。 选择以下方法之一来运行 Quarkus 应用。 为了使 Quarkus 能够连接到 Microsoft Entra ID,请确保在定义上一节中显示的环境变量的 shell 中运行该命令。
在开发模式下运行 Quarkus 应用:
mvn quarkus:dev
在 JVM 模式下运行 Quarkus 应用:
mvn install java -jar target/quarkus-app/quarkus-run.jar
在原生模式下运行 Quarkus 应用:
mvn install -Dnative -Dquarkus.native.container-build ./target/quarkus-ad-1.0.0-SNAPSHOT-runner
如果要尝试不同的模式,请使用 Ctrl+C 停止 Quarkus 应用,然后以另一种模式运行 Quarkus 应用。
测试 Quarkus 应用
运行 Quarkus 应用后,使用专用选项卡打开 Web 浏览器并导航到 http://localhost:8080
。 此时应该会出现欢迎页面,其中包含以用户或管理员身份登录的链接。使用专用选项卡可避免污染您在常规浏览器中可能存在的任何现有 Microsoft Entra ID 活动。
收集两个用户的凭据
在本文中,Microsoft Entra ID 使用每个用户的电子邮件地址作为登录的用户 ID。 按照以下步骤获取管理员用户和一般用户的电子邮件地址:
- 至少以云应用程序管理员身份登录到 Microsoft Entra 管理中心。
- 如果你有权访问多个租户,请使用顶部菜单中的“设置”图标 (),通过“目录 + 订阅”菜单切换到你希望在其中注册应用程序的租户。
- 浏览到“标识”“用户”“所有用户”。>>
- 在列表中找到管理员用户并选择它。
- 找到“用户主体名称”字段。
- 使用字段值旁边的复制图标将用户的电子邮件地址保存到剪贴板。 保存该值以供以后使用。
- 要获取一般用户的电子邮件地址,请按照相同的步骤操作。
使用创建用户时设置的管理员用户和一般用户的密码。
练习应用的功能
按照以下步骤练习功能:
选择“以用户身份登录”链接。 使用之前创建的一般用户登录。 登录后,Microsoft Entra ID 会重定向到配置文件页面,在这里可以看到名称、角色和范围。
如果这是第一次登录,系统会提示更新密码。 按照说明更新密码。
如果系统提示“你的组织需要其他安全信息。请按照提示下载并设置 Microsoft Authenticator 应用程序”,则可以选择“稍后询问”继续测试。
如果系统提示“请求的权限”,请查看应用程序请求的权限。 选择“接受”以继续测试。
选择“注销”,从 Quarkus 应用注销。 Microsoft Entra ID 执行注销。注销后,Microsoft Entra ID 会重定向到欢迎页面。
选择“以管理员身份登录”链接。 Microsoft Entra ID 会重定向到登录页面。 使用之前创建的管理员用户登录。 登录后,Microsoft Entra ID 会重定向到类似的配置文件页面,但具有不同的角色
admin
。再次注销,然后尝试使用之前创建的一般用户以管理员身份登录。 应该会出现一条错误消息,因为一般用户没有
admin
角色。
清理资源
本文并未指导在 Azure 上部署应用。 尽管有 Microsoft Entra ID 资源,但没有应用可清理的 Azure 资源。 若要在 Azure 上部署应用,可以遵循下一部分中的指导。
完成此示例应用的资源后,按照以下步骤清理 Microsoft Entra ID 资源。 删除未使用的 Microsoft Entra ID 资源是一种重要的安全最佳做法。
- 按照“删除在 Microsoft 标识平台注册的应用程序”中的步骤删除创建的应用注册。 只需按照删除组织编写的应用程序部分中的步骤进行操作即可。
- 删除应用注册的行为也应删除企业应用程序。 有关删除企业应用程序的详细信息,请参阅删除企业应用程序。
- 按照如何创建、邀请和删除用户中的步骤删除所创建的用户。
后续步骤
在本快速入门中,将使用 OpenID Connect 通过 Microsoft Entra ID 保护 Quarkus 应用程序。 有关详细信息,请浏览以下资源: