使用 Microsoft Entra ID(以前称为 Microsoft Azure AD)作为 OAuth 2.0 服务器
本指南介绍如何使用以下流程为 RabbitMQ 和 Microsoft Entra ID 作为授权服务器设置 OAuth 2.0
- 通过浏览器访问管理 UI
遵循本指南的先决条件
- 在 https://portal.azure.com 中拥有一个帐户。
- Docker
- Openssl
- 本地克隆 GitHub 存储库,其中包含本示例中使用的所有配置文件和脚本
注册您的应用
当使用 **Entra ID 作为 OAuth 2.0 服务器** 时,您的客户端应用(在本例中为 RabbitMQ)需要一种方法来信任 **Microsoft 身份平台** 向其颁发的安全令牌。
-
建立这种信任的第一步是通过 **在 Entra ID 中的标识平台中注册您的应用**。
提示了解有关 在 Entra ID 中注册应用 的更多信息
-
登录 Entra ID 门户 帐户后,转到 **Entra ID**(如果您无法轻松找到它,请使用搜索栏)。
-
在左侧导航菜单中,单击 **应用注册**。然后选择 **新建注册**。
-
在 **注册应用程序** 窗格中,提供以下信息
- **名称**:您要为应用程序提供的名称(例如:rabbitmq-oauth2)
- **支持的帐户类型**:选择 **仅此组织目录中的帐户(默认目录仅 - 单租户)**(如果您想扩大应用的用户群,可以选择其他选项)
- 在 **选择平台** 下拉列表中,选择 **单页应用程序 (SPA)**
- 将 **重定向 URI** 配置为:
https://127.0.0.1:15671/js/oidc-oauth/login-callback.html
重要Entra ID 仅允许将
https
URI 作为 **重定向 URI**。要了解如何在端口15671
上 为 RabbitMQ 管理 UI 启用 HTTPS,请参阅管理 UI 指南。 -
单击 **注册**。
请注意以下值,因为您稍后需要在 RabbitMQ 端配置
rabbitmq_auth_backend_oauth2
- 目录(租户 ID)
- 应用程序(客户端)ID
-
如果可见,请单击 **端点** 选项卡。
-
在刚刚打开的右侧窗格中,复制 **OpenID Connect 元数据文档** 的值(例如:
https://login.microsoftonline.com/{TENANT_ID}/v2.0/.well-known/openid-configuration
)并在浏览器中打开它。请注意
jwks_uri
键的值(例如:https://login.microsoftonline.com/{TENANT_ID}/discovery/v2.0/keys
),因为您稍后还需要在 RabbitMQ 端配置rabbitmq_auth_backend_oauth2
。 -
如果 **端点** 选项卡不可见,
为您的应用创建 OAuth 2.0 角色
应用角色是在应用注册过程中使用 Entra ID 门户 定义的。当用户登录您的应用程序时,Entra ID 会为用户或服务主体已被授予的每个角色发出 roles
声明(您将在本教程结束时看到它)。
要了解有关 Entra ID 中角色的更多信息,请参阅 Entra ID 文档
-
仍在 Entra ID 门户 中,返回 **Entra ID** 主页。
-
在左侧菜单中,单击 **应用注册**,然后单击您的 **应用程序名称** 以打开您的应用程序 **概述** 窗格。
创建允许访问管理 UI 的角色
-
在左侧菜单中,单击 **应用角色**。
-
然后,单击 **创建应用角色** 以创建一个 OAuth 2.0 角色,该角色将用于授予对 RabbitMQ 管理 UI 的访问权限。
要了解有关在 RabbitMQ 与 OAuth 2.0 一起使用时如何管理权限的更多信息,请参阅 OAuth 2 教程的这一部分
-
在刚刚打开的右侧菜单中,提供所需的信息
- **显示名称**:您要为角色提供的名称(例如:管理 UI 管理员)
- **允许的成员类型**:两者(用户/组 + 应用程序)
- **值**:
Application_ID.tag:administrator
(其中 Application_ID 是本教程前面提到的 应用程序(客户端)ID 的值) - **说明**:简要描述此角色的目标(此处仅授予对 RabbitMQ 管理 UI 的管理员访问权限)
- **您是否要启用此应用角色**:
是
(选中复选框)
-
单击 **应用**。
创建授予对所有资源的配置权限的角色
-
再次单击 **创建应用角色**。您现在将创建一个 OAuth 2.0 角色,该角色将用于授予对所有 RabbitMQ 虚拟主机上的所有资源的配置访问权限。
-
在刚刚打开的右侧菜单中,按照以下方式填写表格
- **显示名称**:您要为角色提供的名称(例如:配置所有虚拟主机)
- **允许的成员类型**:两者(用户/组 + 应用程序)
- **值**:
Application_ID.configure:*/*
(其中 Application_ID 是本教程前面提到的 应用程序(客户端)ID 的值) - **说明**:简要描述此角色的目标(此处授予对 RabbitMQ 实例上所有可用虚拟主机上所有资源的配置权限)
- **您是否要启用此应用角色**:
是
(选中复选框)
-
单击 **应用**。
将应用角色分配给用户
现在,您的应用程序已创建了一些角色,您仍然需要将这些角色分配给一些用户。
-
仍在 Entra ID 门户 中,返回 **Entra ID** 主页,并在左侧菜单中,单击 **企业应用程序**。
-
在新左侧菜单中,选择 **管理 -> 所有应用程序**。使用 **搜索栏** 和/或可用过滤器查找您的应用程序。
-
单击您刚刚创建的要为其分配用户/组角色的应用程序,然后在左侧导航菜单中,选择 **管理 -> 用户和组**。
-
单击 **添加用户/组** 以打开 **添加分配** 窗格。
-
在 **用户** 下面,单击 未选中,然后在右侧刚刚打开的 **用户** 窗格中,搜索并选择您要分配角色的用户/组。
-
选择用户和组后,单击 **选择** 按钮。
-
返回到 **添加分配** 窗格,在 **选择角色** 下面,单击 未选中,然后在右侧刚刚打开的 **选择角色** 窗格中,搜索并选择您要分配给所选用户的角色。
提示如果您的应用程序只有一个角色可用,则它会默认自动选中并变灰。
-
选择一个角色(一次只能选择一个角色),单击 **选择** 按钮,然后单击 **分配** 按钮以完成将用户和组分配到应用的操作。
-
重复所有要分配的角色的操作。
配置自定义签名密钥
为您的应用程序创建签名密钥是可选的。但是,如果您创建了一个签名密钥,则必须在 jwks_uri
中附加包含应用 ID 的 appid
查询参数。否则,标准 jwks_uri 端点将不包含自定义签名密钥,RabbitMQ 将找不到签名密钥来验证令牌的签名。
例如,假设您的应用程序 ID 为 {my-app-id}
,您的租户为 {tenant}
,则 OIDC 发现端点 URI 将为 https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid={my-app-id}
。返回的有效负载包含 jwks_uri
属性,其值为类似于 https://login.microsoftonline.com/{tenant}/discovery/keys?appid=<my-app-idp>
。RabbitMQ 应该使用该 jwks_uri
值进行配置。
配置 RabbitMQ 以使用 Entra ID 作为 OAuth 2.0 身份验证后端
Entra ID 侧的配置已完成。接下来,配置 RabbitMQ 以使用这些资源。
rabbitmq.conf 是一个示例 RabbitMQ 配置,用于启用 Entra ID 作为 OAuth 2.0 身份验证后端,以便于使用 RabbitMQ 管理 UI。
使用以下值更新它:
- 租户 ID,与您在 Entra ID 中注册的应用程序相关联
- 应用程序 ID,与您在 Entra ID 中注册的应用程序相关联
- 来自
https://login.microsoftonline.com/{TENANT_ID}/v2.0/.well-known/openid-configuration
的 jwks_uri 密钥的值
auth_backends.1 = rabbit_auth_backend_oauth2
auth_backends.2 = rabbit_auth_backend_internal
management.oauth_enabled = true
management.oauth_client_id = {PUT YOUR AZURE AD APPLICATION ID}
management.oauth_provider_url = https://login.microsoftonline.com/{YOUR_ENTRA_ID_TENANT_ID}
auth_oauth2.resource_server_id = {PUT YOUR AZURE AD APPLICATION ID}
auth_oauth2.additional_scopes_key = roles
auth_oauth2.jwks_url = {PUT YOUR ENTRA ID JWKS URI VALUE}
启动 RabbitMQ
运行以下命令来运行 RabbitMQ Docker 镜像
export MODE=entra
make start-rabbitmq
这将启动一个名为 rabbitmq
的 Docker 容器,其中包含启用了 HTTPS 的 RabbitMQ 管理 UI/API,并根据您在 rabbitmq.conf 中提供的本教程步骤中提供的配置信息,配置为使用您的 Entra ID 作为 OAuth 2.0 身份验证后端。
自动生成 TLS 证书和密钥对
Entra ID 仅允许将 https
URI 作为 **重定向 URI**。要了解如何在端口 15671
上 为 RabbitMQ 管理 UI 启用 HTTPS,请参阅管理 UI 指南。
当您首次使用 MODE=entra
运行 make start-rabbitmq
时,在 RabbitMQ 部署之前,会为 RabbitMQ 生成一个 TLS 证书,以便它能够监听 HTTPS 端口 15671。
脚本将在 conf/entra/certs
中生成以下文件:
- cacert.pem:一个用于生成和签署 RabbitMQ 自签名证书的自定义证书颁发机构
- cert.pem:一个自签名证书(cn=localhost)
- key.pem:与
cert.pem
证书关联的私钥
这些文件将在本教程的后续步骤中被挂载到 rabbitmq
容器中,它们将用于为 RabbitMQ 管理 UI 和 HTTP API 配置 HTTPS。
验证 RabbitMQ 管理 UI 访问权限
转到 RabbitMQ 管理 UI https://127.0.0.1:15671
。根据您的浏览器,忽略安全警告(由您使用自签名证书引起)以继续。
在 RabbitMQ 管理 UI 页面上,单击 Click here to log in 按钮,使用您的 Entra ID 用户进行身份验证。第一次登录时,您可能需要进行授权(取决于您这边应用于 Entra AD 的策略)。
在首次登录时,您可能会遇到名为 AADSTS90008
的错误。这是一个 已知问题。
再次单击 Click here to log in 按钮,错误将消失。
最后,您将被重定向回 RabbitMQ 管理 UI。
Entra AD 会发出如下所示的访问令牌。权限在 roles
声明中管理。您已使用 {extra_scopes_source, <<"roles">>},
配置 RabbitMQ,这意味着 RabbitMQ 将使用 roles
声明中的范围来为已登录用户定义权限。
{
"aud": "30b61ef8-72d7-4e40-88f2-6e16c8d3fd88",
"iss": "https://sts.windows.net/1ffc6121-590e-4aa5-bf47-c348674069cb/",
"iat": 1655740039,
"nbf": 1655740039,
"exp": 1655744211,
"acr": "1",
"aio": "AUQAu/8TAAAAjvwucwL4nZe83vNZvg6A7sAPscI9zsGvRs8EuT7aVhubpmhRnxJ+X7nbkISoP5eBBMxoi2yiCclnH2Ocjjzsqw==",
"amr": [
"wia"
],
"appid": "30b61ef8-72d7-4e40-88f2-6e16c8d3fd88",
"appidacr": "1",
"email": "baptiste.daroit@company.com",
"idp": "https://sts.windows.net/b3f4f7c2-72ce-4192-aba4-d6c7719b5766/",
"in_corp": "true",
"ipaddr": "xxx.xxx.xxx.xxx",
"name": "Baptiste DA ROIT",
"oid": "cf2df3b4-03df-4e1e-b5c0-f232932aaead",
"rh": "0.AR8AgCG80x7L90C1mhVBBXQzQjgoklctsdBMtgYVWFwc4tgfAMQ.",
"roles": [
"30b61ef8-72d7-4e40-88f2-6e16c8d3fd88.tag:monitoring",
"30b61ef8-72d7-4e40-88f2-6e16c8d3fd88.configure:*/*"
],
"scp": "User.Read",
"sub": "6aBzW3a1FOTTrnlZEuC1SmwG0sRjVgQU49DvrYK6Rqg",
"tid": "1ffc6121-590e-4aa5-bf47-c348674069cb",
"unique_name": "baptiste.daroit@company.com",
"uti": "QHqwThTqQEK9iMdnRuD_AA",
"ver": "1.0"
}