OAuth 2.0 身份验证后端
概述
此 RabbitMQ 身份验证/授权后端 插件允许应用程序(客户端)和用户使用 JWT 编码的 OAuth 2.0 访问令牌进行身份验证和授权。
还有一个配套的 OAuth 2 特定问题故障排除指南。
目录
如何配置它
工作原理
基本用法
高级用法
特定身份提供商的示例
如何配置它
这是一个关于如何为大多数用例配置 OAuth 2.0 身份验证的分步指南,例如
- 您正在使用符合 OpenId Connect 的身份提供商
- 您希望 RabbitMQ 在管理 UI 中触发 OAuth 2.0 身份验证。 这被称为服务提供商发起的登录。 这与用户需要通过其他方式已获得的令牌来到 RabbitMQ 是不同的。
先决条件
步骤 1:启用插件
OAuth 2 插件必须像所有其他插件一样被激活(或 预配置)后才能使用。 有一个常见的文件位于 /etc/rabbitmq/enabled_plugins
。 如下所示添加 OAuth 2 插件
[rabbitmq_management,rabbitmq_shovel,rabbitmq_auth_backend_oauth2].
步骤 2:将 OAuth 2.0 配置为身份验证后端之一
编辑您的 rabbitmq.conf
文件,通常位于 /etc/rabbitmq
,并添加 OAuth 2.0 后端。 例如,以下配置添加 OAuth 2.0 作为唯一的身份验证后端
auth_backends.1 = rabbit_auth_backend_oauth2
为符合 OpenId Connect 的身份提供商配置 OAuth 2.0
如今,大多数身份提供商都符合 OpenId Connect。 至少,这意味着它们公开了一个 HTTP 端点,称为Discovery endpoint,挂载在 /.well-known/openid-configuration
。 通过此端点,RabbitMQ 发现成功进行 OAuth 2.0 身份验证所需的所有端点。 以下身份提供商符合 OpenId Connect
- UAA
- Keycloak
- Auth0
- Entra ID (又名 Azure)
- Okta
步骤 1:配置与 RabbitMQ 关联的 OAuth 2.0 资源名称
auth_oauth2.resource_server_id = rabbitmq
OAuth 2.0 令牌具有一个名为 audience
的属性。 此属性列出了令牌旨在用于的所有 OAuth 2.0 资源。 RabbitMQ 希望在其中一个 audience
值中找到其 resource_server_id
。 如果未找到,则令牌将被拒绝,并且身份验证失败。
虽然不建议这样做,但您可以通过添加以下配置来禁用受众验证
auth_oauth2.verify_aud = false
步骤 2:配置身份提供商的根 URL
按如下方式配置身份提供商的根 URL
auth_oauth2.issuer = https://keycloak:8443/realms/test
它必须是 HTTPS URL。 如果您的身份提供商使用自签名 CA 证书签名的证书,则可以通过将以下行添加到您的配置中来配置 CA 证书
auth_oauth2.https.cacertfile = <path_to_your_ca_cert>
步骤 3:配置哪些令牌属性包含用户名
RabbitMQ 需要知道用户名,以便用于日志记录目的,并在管理 UI 中显示它。 默认情况下,RabbitMQ 在令牌的属性 sub
中查找用户名,如果未找到,则使用 client_id
。
在这里,您配置 RabbitMQ 首先使用 user_name
,如果未找到,则使用 preferred_username
。
auth_oauth2.preferred_username_claims.1 = user_name
auth_oauth2.preferred_username_claims.2 = preferred_username
步骤 4:配置哪些令牌属性包含作用域(又名权限)
默认情况下,RabbitMQ 始终在令牌的属性 scope
中查找作用域。 如果您的作用域位于不同的属性中,则可以配置该属性的名称。
给定以下配置,RabbitMQ 在属性 scope
和 extra_scope
中搜索作用域
auth_oauth2.additional_scopes_key = extra_scope
属性的值可以是空格分隔的作用域字符串,也可以是作用域的 JSON 列表。
自 4.1 起,您可以配置空格分隔的令牌属性列表。 示例令牌
{
...
"authorization": {
"permissions": [
{
"scopes": [
"rabbitmq.read:*/*"
],
"rsid": "2c390fe4-02ad-41c7-98a2-cebb8c60ccf1",
"rsname": "allvhost"
},
{
"scopes": [
"rabbitmq.write:vhost1/*"
],
"rsid": "e7f12e94-4c34-43d8-b2b1-c516af644cee",
"rsname": "vhost1"
},
{
"scopes": [
"rabbitmq.tag:administrator"
],
"rsid": "12ac3d1c-28c2-4521-8e33-0952eff10bd9"
}
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "email profile openid",
"extra_scope": "rabbitmq.tag:administrator rabbitmq.tag:management",
...
}
您可以配置 RabbitMQ 以从 authorization.permissions.scopes
下方以及 resource_access.account.roles
和 extra_scope
获取作用域,如下所示
auth_oauth2.additional_scopes_key = extra_scope realm_access.roles resource_access.account.roles
步骤 5:确保您的作用域是可识别的 RabbitMQ 作用域
确保令牌中包含的作用域是可识别的 RabbitMQ 作用域。
以下是可识别的 RabbitMQ 作用域的示例
-
rabbitmq.tag:administrator
这里rabbitmq
是您在第一步中配置的resource_server_id
的名称。tag:administrator
授予管理 UI 管理员角色。 -
rabbitmq.configure:*/*
此作用域授予configure
权限。 第一个通配符对应于 vhost,第二个通配符对应于队列/交换机。
它们都以一个前缀开头,默认情况下,该前缀必须与您在步骤 1 中配置的资源名称匹配。
如果您的作用域是可识别的 RabbitMQ 作用域,但它们以不同的前缀开头。 您可以按如下方式配置您的自定义前缀
auth_oauth2.scope_prefix = api://
在上面的示例中,您表示您的作用域类似于 api://tag:administrator
。
有关作用域前缀的更多信息,请查看 作用域前缀。
步骤 6:将自定义权限/作用域映射到 RabbitMQ 作用域
如果令牌中的作用域不是可识别的 RabbitMQ 作用域,则此步骤是强制性的。 在上一步中,您看到了可识别的 RabbitMQ 作用域的外观。
在这里,您将两个自定义作用域 admin
和 developer
配置到 RabbitMQ 作用域上
auth_oauth2.scope_aliases.admin = rabbitmq.tag:administrator rabbitmq.read:*/
auth_oauth2.scope_aliases.developer = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
有关映射作用域的更多信息,请查看 作用域别名。
步骤 7:OAuth 2.0 身份验证已完成,用于消息传递协议
RabbitMQ 已准备好对通过支持的消息传递协议之一连接的应用程序进行身份验证。 如果您还想在管理 UI 中启用 OAuth 2.0,请继续执行以下步骤。
步骤 8:在管理 UI 上启用 OAuth 2.0
以下步骤配置 RabbitMQ 以使用 OAuth 2.0 通过其身份提供商对用户进行身份验证并获取令牌。 这被称为 服务提供商发起的登录。
management.oauth_enabled = true
在管理 UI 中启用 OAuth 2.0 后,基本身份验证将被禁用,除非您添加以下配置。
management.oauth_disable_basic_auth = false
有关更多信息,请查看 允许管理 UI 的基本身份验证和 OAuth 2 身份验证
步骤 9:配置 OAuth client_id
management.oauth_client_id = <Your_Client_Id_from_your_identity_provider>
身份提供商 UAA
除了 client_id
之外还需要 client_secret
。 这在其余身份提供商中不是必需的。 在您的身份提供商中为 RabbitMQ 配置的 OAuth 客户端应为 public web application
类型,而不是 confidential
类型。 后者需要 client_secret
。
步骤 10:配置管理 UI 从您的身份提供商请求哪些作用域
当 RabbitMQ 从身份提供商请求令牌时,它必须指定令牌应包含哪些作用域。 通过配置变量 management.oauth_scopes
,您提供了一个空格分隔的作用域列表。
您始终包含前两个作用域 openid
和 profile
,后跟任何 RabbitMQ 作用域。
management.oauth_scopes = openid profile rabbitmq.tag:management
某些身份提供商可能包含比请求的作用域更多的作用域。 这将完全取决于实际的身份提供商实现。
工作原理
先决条件
要使用 OAuth 2 插件,所有 RabbitMQ 节点都必须
- 配置为使用 rabbit_auth_backend_oauth2 后端.
- 配置资源服务 ID (
resource_server_id
)。 RabbitMQ 集群成为 OAuth 2.0 资源,这是它的标识符。 - 配置 OAuth 2.0 提供商的颁发者 URL,或 JWKS URL,或直接配置 OAuth 2.0 提供商用于签署令牌的签名密钥
以下是支持 OAuth 2.0 身份验证的最小配置
要在管理插件中激活它,您需要 其他配置。
auth_oauth2.resource_server_id = new_resource_server_id
auth_oauth2.issuer = https://my-oauth2-provider.com/realm/rabbitmq
根据之前的配置,呈现给 RabbitMQ 进行身份验证的 JWT 令牌必须
- 进行数字签名。
- 在
aud
字段中具有与resource_server_id
值匹配的值。 - 具有必须与
resource_server_id
值匹配的作用域。 例如new_resource_server_id.read:*/*
。
此外,https://my-oauth2-provider.com/realm/rabbitmq/.well-known/openid-configuration
端点必须返回 OpenID 提供商配置,其中包括 JKWS URL 以下载签名密钥。
.well-known/openid-configuration 是 OpenID 提供商配置端点的 OpenID 标准路径
如果您的提供商公开了不同的路径和/或 OpenId discovery endpoint 需要一些额外的 http 参数,您可以按如下方式配置它们
auth_oauth2.discovery_endpoint_path = my/custom/path
auth_oauth2.discovery_endpoint_params.appid = some-app-id
下一节包含有关身份验证期间发生的事情以及如何在基本配置之外配置 OAuth 2.0 的更多详细信息。
授权流程
此插件不与任何 OAuth 2.0 提供商通信,以便对用户进行身份验证和授予访问权限。 相反,它解码客户端提供的访问令牌,并根据令牌中找到的作用域授权用户。
令牌必须进行数字签名,否则不被接受。 RabbitMQ 必须具有签名密钥才能验证签名。 您可以配置 OAuth 2.0 提供商将使用的签名密钥,或者使用以下两个端点之一配置 RabbitMQ
-
JWKS 端点:这是返回用于数字签名令牌的签名密钥的 HTTP 端点
-
OpenID 提供商配置端点:此端点返回提供商的配置,包括其所有端点,最重要的是 JWKS 端点
当您使用前两个端点之一配置 RabbitMQ 时,RabbitMQ 必须发出 HTTP 请求(或者两个,如果您指定后一个端点)以下载签名密钥。 这是对任何尚未下载的签名密钥执行一次的操作。 当 OAuth 2.0 提供商轮换签名密钥时,较新的令牌会引用 RabbitMQ 尚不拥有的新签名密钥,这将触发再次下载较新的签名密钥。
令牌可以是任何 JWT 令牌,其中包含 scope
和 aud
字段。
按时间顺序排列,以下是客户端应用程序想要连接到 RabbitMQ 的消息传递协议之一(例如 AMQP)时发生的事件序列
- 客户端应用程序从 OAuth 2.0 提供商请求 access_token。
- 访问令牌必须在
scope
字段中包含 RabbitMQ 支持的 作用域(可以通过在auth_oauth2.additional_scopes_key
中设置新字段的名称,为 作用域 使用不同的字段)。 - 客户端应用程序在连接到 RabbitMQ 的消息传递协议时,将令牌作为密码传递。 用户名字段将被忽略。
- RabbitMQ 验证令牌的签名。 为了验证它,RabbitMQ 必须具有签名密钥,或者如前几节所述从 JWKS 端点下载它们。
- RabbitMQ 验证令牌是否具有 audience 声明,并且其值与
resource_server_id
匹配(可以通过将auth_oauth2.verify_aud
设置为false
来禁用此操作)。 - RabbitMQ 将令牌中找到的 作用域 转换为 RabbitMQ 权限(与 RabbitMQ 内部数据库中使用的权限相同)。
rabbitmq.conf 中可配置的变量
键 | 文档 |
---|---|
auth_oauth2.resource_server_id | 资源服务器 ID |
auth_oauth2.resource_server_type | 使用 富授权请求 令牌格式时所需的资源服务器类型 |
auth_oauth2.additional_scopes_key | 配置 插件以在其他字段中查找作用域。 |
auth_oauth2.scope_prefix | 配置所有作用域的前缀。 默认值是 auth_oauth2.resource_server_id 后跟点 . 字符。 |
auth_oauth2.preferred_username_claims | JWT 声明列表,用于查找与令牌关联的用户名。 |
auth_oauth2.default_key | 默认签名密钥的 ID。 |
auth_oauth2.signing_keys | 签名密钥文件的路径。 |
auth_oauth2.issuer | 授权服务器的 颁发者 URL,用于发现诸如 jwks_uri 之类的端点和/或将 RabbitMQ 管理用户重定向到此处以登录并获取令牌。 |
auth_oauth2.jwks_uri | JWKS 端点的 URL。 根据 JWT 规范,端点 URL 必须是 https。 如果您设置 auth_oauth2.issuer ,则为可选。 如果设置了此 URL,它将覆盖通过 discovery endpoint 发现的 jwks_uri 。 |
auth_oauth2.jwks_url | 此变量已弃用,您应该改用 auth_oauth2.jwks_uri 。 在 RabbitMQ 4.2.0 中,将删除此变量。 同时,RabbitMQ 支持它,直到您更改配置。 |
auth_oauth2.token_endpoint | OAuth 2.0 令牌端点的 URL。 如果您设置 auth_oauth2.issuer ,则为可选。 如果设置了此 URL,它将覆盖通过 discovery endpoint 发现的 token_endpoint 。 |
auth_oauth2.https.cacertfile | 包含 PEM 编码的 CA 证书的文件路径。 CA 证书用于连接到以下任何端点:jwks_uri 、token_endpoint 或 discovery endpoint。 |
auth_oauth2.https.depth | 在有效的 证书路径 中,可能跟随对等证书的非自颁发中间证书的最大数量。 默认值为 10。 |
auth_oauth2.https.peer_verification | 配置 对等验证。 可用值:verify_none 、verify_peer 。 如果操作系统中安装了受信任的 CA 或设置了 auth_oauth2.https.cacertfile ,则默认值为 verify_peer 。 已弃用:此变量将很快被 auth_oauth2.https.verify 替换。 用户应停止使用此变量。 |
auth_oauth2.https.fail_if_no_peer_cert | 与 auth_oauth2.https.peer_verification = verify_peer 一起使用。 当设置为 true 时,如果客户端未能提供证书,TLS 连接将被拒绝。 默认值为 false 。 |
auth_oauth2.https.hostname_verification | 为密钥服务器启用支持通配符的主机名验证。 可用值:wildcard 、none 。 默认值为 none 。 |
auth_oauth2.https.crl_check | 执行 CRL 验证 (证书吊销列表) 验证。 默认值为 false。 |
auth_oauth2.proxy | 配置显式 转发代理,用于连接到 auth_oauth2.issuer URL。 这是一个仅限商业的功能。 有关如何使用它的更多信息,请参见 此示例。 |
auth_oauth2.algorithms | 限制 可用的算法。 |
auth_oauth2.verify_aud | 是否验证 令牌的 aud 字段。 默认值为 true 。 |
auth_oauth2.resource_servers | 多个 OAuth 2.0 资源配置. |
auth_oauth2.oauth_providers | 多个 OAuth 2.0 提供商配置. |
auth_oauth2.default_oauth_provider | 用于 auth_oauth2.resource_servers 的 OAuth 2.0 提供商的 ID,该提供商未指定任何 ID(通过变量 oauth_provider_id ),或者当 auth_oauth2.jwks_uri 和 auth_oauth2.issuer 都缺失时使用。 |
资源服务器 ID
RabbitMQ 集群必须至少配置一个资源服务器标识符。 如果它只有一个资源,则在 auth_oauth2.resource_server_id
变量中配置它,并且它是强制性的。 如果 RabbitMQ 集群有多个 OAuth 资源,则它们在 auth_oauth2.resource_servers.<index>
下配置,在这种情况下,auth_oauth2.resource_server_id
变量不是强制性的。
RabbitMQ 将资源服务器标识用于以下两个目的
- 验证令牌的受众 (
aud
),其值必须包含资源服务器标识符。 但是,可以禁用此验证。 - 在管理 UI 中启动 OAuth 2.0 授权码流程。 这是用于验证用户身份并获取其访问令牌的流程。 RabbitMQ 必须在名为
resource
的请求属性中包含资源服务器标识符。
作用域前缀
OAuth 2.0 令牌使用作用域来传达特定客户端被授予的权限集。 作用域是自由格式的字符串。
默认情况下,resource_server_id
后跟点 (.
) 字符是用作作用域的前缀,以避免作用域冲突(或意外重叠)。 但是,在某些环境中,不可能使用 resource_server_id
作为所有作用域的前缀。 对于这些环境,有一个名为 scope_prefix
的新变量,它会覆盖默认的作用域前缀。
给定以下配置,与权限 read:*/*
关联的作用域是 api://read:*/*
。
...
auth_oauth2.scope_prefix = api://
...
要使用空字符串作为前缀,请使用以下配置
...
auth_oauth2.scope_prefix = ''
...
作用域别名
当无法在身份提供商 (IDP) 端配置 RabbitMQ 格式的作用域时,作用域别名是必要的
作用域别名是自定义 JWT 令牌作用域与一组 RabbitMQ 特定作用域之间的映射。 自定义作用域也可以定义为 RabbitMQ 的 OAuth 2 子系统无法识别的任何作用域。
当无法在身份提供商 (IDP) 端配置 RabbitMQ 格式的作用域时,作用域别名是必要的。 相反,在 IDP 端配置一组名称,并将其映射到 RabbitMQ 可以解析和使用的一组作用域。
例如,让我们考虑一个具有以下两个角色的身份提供商
管理员
开发者
这些角色应映射到以下 RabbitMQ 作用域
admin
到rabbitmq.tag:administrator rabbitmq.read:*/
developer
到rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
以下 rabbitmq.conf
示例使用作用域别名执行上述映射。 映射可以是一对一或一对多
# ...
# the "admin" role above
auth_oauth2.scope_aliases.admin = rabbitmq.tag:administrator rabbitmq.read:*/
# the "developer" role above
auth_oauth2.scope_aliases.developer = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
# ...
有时,别名可能必须使用特殊字符和符号,包括分隔符 .
。 在这些情况下,请按如下方式配置作用域别名
# ...
auth_oauth2.scope_aliases.1.alias = api://admin
auth_oauth2.scope_aliases.1.scope = rabbitmq.tag:administrator rabbitmq.read:*/
auth_oauth2.scope_aliases.2.alias = api://developer.All
auth_oauth2.scope_aliases.2.scope = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
# ...
签名密钥文件
以下配置声明了两个签名密钥,并配置了默认签名密钥的 kid。 有关更多信息,请查看 配置签名密钥 部分。
auth_oauth2.resource_server_id = new_resource_server_id
auth_oauth2.default_key = id1
auth_oauth2.signing_keys.id1 = test/config_schema_SUITE_data/certs/key.pem
auth_oauth2.signing_keys.id2 = test/config_schema_SUITE_data/certs/cert.pem
auth_oauth2.algorithms.1 = HS256
auth_oauth2.algorithms.2 = RS256
JWKS 端点
以下配置设置了 JWKS 端点,RabbitMQ 从该端点下载签名密钥,使用配置的 CA 证书和 TLS 变量。
auth_oauth2.resource_server_id = new_resource_server_id
auth_oauth2.jwks_uri = https://my-jwt-issuer/jwks.json
auth_oauth2.https.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
auth_oauth2.https.peer_verification = verify_peer
auth_oauth2.https.depth = 5
auth_oauth2.https.fail_if_no_peer_cert = true
auth_oauth2.https.hostname_verification = wildcard
auth_oauth2.algorithms.1 = HS256
auth_oauth2.algorithms.2 = RS256
多资源服务器配置
每个 auth_oauth2.resource_servers.<id/index>.
条目都具有下表所示的变量。 除了变量 id
和 oauth_provider_id
之外,如果资源未配置变量,则 RabbitMQ 使用在根级别配置的变量。 例如,如果资源 auth_oauth2.resource_servers.prod
未配置 preferred_username_claims
变量,则 RabbitMQ 对资源 prod
使用在 auth_oauth2.preferred_username_claims
中配置的值。
键 | 文档 |
---|---|
id | 资源服务器 ID。 |
resource_server_type | 使用 富授权请求 令牌格式时所需的资源服务器类型。 |
additional_scopes_key | 配置插件以在其他字段中查找作用域(映射到旧格式中的 additional_rabbitmq_scopes )。 |
scope_prefix | 配置所有作用域的前缀。 默认值是 auth_oauth2.resource_server_id 后跟点 . 字符。 |
scope_aliases | 配置作用域别名 |
preferred_username_claims | JWT 声明列表,用于查找与令牌关联的用户名,以逗号分隔。 |
oauth_provider_id | 与此资源关联的 OAuth 提供商的标识符。 RabbitMQ 使用此 OAuth 提供商颁发的签名密钥来验证受众与此资源的 id 匹配的令牌。 |
每个 OAuth 2 提供商的所有可用可配置参数都在 单独的部分 中记录。
通常,数值用作 index
,例如 auth_oauth2.resource_servers.1.id = rabbit_prod
。 但是,它可以是任何字符串,例如 auth_oauth2.resource_servers.rabbit_prod.jwks_uri = http://some_url
。 默认情况下,index
是资源服务器的 id。 但是,您可以通过 id
变量覆盖它,例如 auth_oauth2.resource_servers.1.id = rabbit_prod
。
这是一个配置两个资源(prod
和 dev
)的示例,这些资源由同一身份提供商管理的用户和客户端使用,该身份提供商的颁发者 url 为 https://my-idp.com/
auth_oauth2.issuer = https://my-idp.com/
auth_oauth2.resource_servers.1.id = prod
auth_oauth2.resource_servers.2.id = dev
有关如何配置它们的更多信息,请参见名为 多资源服务器 的高级用法部分。
多 OAuth 提供商配置
每个 auth_oauth2.oauth_providers.{id/index}
条目都具有以下子键。
键 | 文档 |
---|---|
issuer | OAuth 提供商的 URL。 它用于构建 discovery endpoint URL 和/或将 RabbitMQ 管理用户重定向到此处以登录并获取令牌。 |
discovery_endpoint_path | 用于 OpenId discovery endpoint 的路径。 默认值为 .well-known/openid-configuration |
discovery_endpoint_params | 发送到 OpenId discovery endpoint 的 HTTP 查询参数列表。 |
token_endpoint | OAuth 2.0 令牌端点的 URL。 如果您配置了 issuer ,则为可选。 |
jwks_uri | JWKS 端点的 URL。 根据 JWT 规范,端点 URL 必须是 https。 如果您设置 issuer ,则此变量是可选的。 |
https.cacertfile | 包含 PEM 编码的 CA 证书的文件路径,用于连接 issuer 和/或 jwks_uri URL。 |
https.depth | 在有效的 证书路径 中,可能跟随对等证书的非自颁发中间证书的最大数量。 默认值为 10。 |
https.verify | 配置 对等验证。 可用值:verify_none 、verify_peer 。 如果操作系统中安装了受信任的 CA 或设置了 auth_oauth2.https.cacertfile ,则默认值为 verify_peer 。 |
https.fail_if_no_peer_cert | 与 auth_oauth2.https.peer_verification = verify_peer 一起使用。 当设置为 true 时,如果客户端未能提供证书,TLS 连接将被拒绝。 默认值为 false 。 |
https.hostname_verification | 为密钥服务器启用支持通配符的主机名验证。 可用值:wildcard 、none 。 默认值为 none 。 |
https.crl_check | 执行 CRL 验证 (证书吊销列表) 验证。 默认值为 false。 |
auth_oauth2.proxy | 配置显式 转发代理,用于连接到 issuer URL。 这是一个仅限商业的功能。 有关如何使用它的更多信息,请参见 此示例。 |
signing_keys | 指向签名密钥文件的本地文件系统路径。文件必须存在且可读。 |
default_key | 默认签名密钥的 ID。 |
algorithms | 用于限制启用的算法列表。 |
以下示例配置了两个资源(prod
和 dev
),其中每个资源由两个不同的身份提供程序管理
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.resource_servers.1.id = prod
auth_oauth2.resource_servers.1.oauth_provider_id = idp_prod
auth_oauth2.resource_servers.2.id = dev
auth_oauth2.resource_servers.2.oauth_provider_id = idp_dev
auth_oauth2.oauth_providers.idp_prod.issuer = https://idp_prod.com
auth_oauth2.oauth_providers.idp_dev.issuer = https://idp_dev.com
有关如何配置它们的更多信息,请参阅名为多 OAuth 提供程序的高级用法部分。
令牌验证
当 RabbitMQ 接收到 JWT 令牌时,它会在接受令牌之前对其进行验证。
必须进行数字签名
令牌必须带有数字签名,并且可以选择性地带有 kid
标头属性,该属性标识 RabbitMQ 应用于验证签名的密钥。
不得过期
如果存在,RabbitMQ 将使用此字段 exp
(exp) 来验证令牌。它包含过期时间,超过此时间后,JWT 绝不能被接受进行处理。
受众必须拥有/匹配 resource_server_id
aud
(受众) 标识 JWT 的接收者和/或资源服务器。
默认情况下,RabbitMQ 使用此字段来验证令牌。可以通过将 auth_oauth2.verify_aud
设置为 false
来禁用此验证。启用验证后,此 aud
字段必须与 resource_server_id
值匹配,或者,在列表的情况下,它必须包含 resource_server_id
值。
令牌过期和刷新
在 RabbitMQ 中,令牌过期和刷新过程在 AMQP 1.0 和 AMQP 0.9.1 协议之间有所不同。
对于 AMQP 1.0,如果现有连接上的最新令牌过期,RabbitMQ 将断开客户端连接。为了防止断开连接,客户端可以在令牌过期之前主动刷新令牌。客户端可以通过发送 HTTP-over-AMQP 1.0 请求来设置新令牌。此请求在 /auth/tokens
端点上使用 PUT
操作,令牌包含在正文中作为 二进制 AMQP 值。RabbitMQ 的 AMQP 1.0 客户端在 Java、.NET 和 Erlang 中支持令牌刷新。
对于 AMQP 0.9.1,当现有连接上的令牌过期时,broker 会在有限的时间后拒绝进一步的操作,但不会断开客户端连接。要刷新令牌,如果客户端支持,客户端可以使用 AMQP 0.9.1 update-secret 协议方法。有关示例,请参阅 Java 客户端文档。如果客户端不支持 update-secret
,则必须断开连接并使用新令牌重新连接。
Scope 到权限转换
Scope 被转换为针对提供的令牌对 RabbitMQ 资源的权限授予。
当前的 scope 格式为 <permission>:<vhost_pattern>/<name_pattern>[/<routing_key_pattern>]
,其中
<permission>
是访问权限(configure
、read
或write
)<vhost_pattern>
是令牌有权访问的 vhost 的通配符模式。<name_pattern>
是资源名称的通配符模式<routing_key_pattern>
是主题授权中路由键的通配符模式
通配符模式是带有可选通配符 *
的字符串,它匹配任何字符序列。
通配符模式匹配如下
*
匹配任何字符串foo*
匹配任何以foo
开头的字符串*foo
匹配任何以foo
结尾的字符串foo*bar
匹配任何以foo
开头并以bar
结尾的字符串
一个模式中可以有多个通配符
start*middle*end
*before*after*
要在通配符模式中使用特殊字符(例如 *
、%
或 /
),模式必须是 URL 编码的。
以下是一些常见的权限示例
read:*/*
(read:*/*/*
) - 对任何 vhost 上的任何资源的读取权限write:*/*
(write:*/*/*
) - 对任何 vhost 上的任何资源的写入权限read:vhost1/*
(read:vhost1/*/*
) - 对vhost1
vhost 上的任何资源的读取权限read:vhost1/some*
- 对vhost1
vhost 上所有以some
开头的资源的读取权限write:vhost1/some*/routing*
- 主题写入权限,用于发布到以some
开头的交换机,路由键以routing
开头read:*/*/*
和write:*/*/*
- 在任何路由键的主题交换机上绑定队列所需的队列绑定权限
有关更多示例,请参阅 通配符匹配测试套件 和 scopes 测试套件。
默认情况下,如果未配置 scope_prefix
,则 scope 以 resource_server_id
开头,后跟点 (.
) 字符。例如,如果 resource_server_id
是 “my_rabbit”,则启用从任何 vhost 读取的 scope 将是 my_rabbit.read:*/*
。
如果配置了 scope_prefix
,则 scope 的前缀如下:<scope_prefix><permission>
。例如,如果 scope_prefix
是 api://
且权限是 read:*/*
,则 scope 将是 api://read:*/*
主题交换机 scope
上一节详细解释了权限如何映射到 scope。本节更具体地解释了您需要在 主题交换机 上操作所需的 scope。
要将队列绑定和/或取消绑定到/从 主题交换机,您需要具有以下 scope
- 队列和路由键的 write 权限 ->
rabbitmq.write:<vhost>/<queue>/<routingkey>
例如
rabbitmq.write:*/*/*
- 交换机和路由键的 read 权限 ->
rabbitmq.write:<vhost>/<exchange>/<routingkey>
例如
rabbitmq.read:*/*/*
要发布到 主题交换机,您需要具有以下 scope
- 交换机和路由键的 write 权限 ->
rabbitmq.write:<vhost>/<exchange>/<routingkey>
例如
rabbitmq.write:*/*/*
OAuth 2.0 授权后端在检查主题权限时支持变量扩展。它支持其值为纯字符串的 JWT 声明,以及 vhost
变量。
例如,使用以下令牌连接到 vhost prod
的用户应该对所有以 x-prod-
开头的交换机以及任何以 u-bob-
开头的路由键具有写入权限
{
"sub" : "bob",
"scope" : [ "rabbitmq.write:*/x-{vhost}-*/u-{sub}-*" ]
}
Scope 和标签
RabbitMQ 中的用户可以具有与其关联的标签。标签用于控制对管理插件的访问。
在 OAuth 上下文中,可以使用类似 <resource_server_id>.tag:<tag>
的格式将标签添加为 scope 的一部分。例如,如果 resource_server_id
是 “my_rabbit”,则授予对具有 monitoring
标签的管理插件的访问权限的 scope 将是 my_rabbit.tag:monitoring
。
基本用法
配置 OAuth 2.0 提供程序的颁发者
在 RabbitMQ 3.13 之前,用户必须配置 JWKS 端点(即 auth_oauth2.jwks_uri
变量)或静态配置签名密钥。现在,用户只需配置 OpenID 提供程序的 颁发者 URL,RabbitMQ 即可从此 URL 下载 OpenID 提供程序配置,其中包括 JWKS 端点以及其他上下文中可能有用的其他端点。
通常,此 颁发者 URL 与管理插件中配置的 URL (management.oauth_provider_url
) 相同。从现在开始,您只需要配置一个 URL,由 auth_oauth2.issuer
变量指定。除非在 颁发者 URL 未托管登录页面的极端情况下。在这些情况下,用户在 management.oauth_provider_url
变量中配置登录页面。
使用颁发者的示例配置
auth_oauth2.resource_server_id = my_rabbit_server
auth_oauth2.issuer = https://my-idp-provider/somerealm
配置 jwks_uri
而不是颁发者的示例配置
auth_oauth2.resource_server_id = my_rabbit_server
auth_oauth2.jwks_uri = "https://my-jwt-issuer/jwks.json
如果您同时配置了这两个端点,RabbitMQ 将使用 jwks_uri
,因为它不需要通过 issuer
URL 发现它。
关于 jwks_uri
或 issuer
url 的 TLS 变量的说明:TLS 变量(例如 cacertfile
)的配置方式如下,无论您使用哪个 URL
...
auth_oauth2.https.cacertfile = /opts/certs/cacert.pem
...
非常重要:自 RabbitMQ 3.13 起,如果未设置 auth_oauth2.https.peer_verification
变量,只要操作系统中安装了受信任的证书或用户配置了 auth_oauth2.https.cacertfile
,RabbitMQ 就会将其设置为 verify_peer
。
配置签名密钥
目前,当 RabbitMQ 可以自动下载签名密钥(如上一节所述)时,您很少需要使用签名密钥配置 RabbitMQ。但是,RabbitMQ 支持那些您需要静态配置签名密钥的极端情况,或者当您需要支持对称签名密钥而不是最广泛使用的非对称密钥时。
以下示例使用 Cloud Foundry UAA 作为 OAuth 2.0 提供程序。
要从 OAuth 2.0 提供程序 UAA 获取签名密钥,请使用 token_key 端点 或 uaac (uaac signing key
命令)。
以下字段是必需的:kty
、value
、alg
和 kid
。
假设 UAA 报告以下签名密钥信息
uaac signing key
kty: RSA
e: AQAB
use: sig
kid: a-key-ID
alg: RS256
value: -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2dP+vRn+Kj+S/oGd49kq
6+CKNAduCC1raLfTH7B3qjmZYm45yDl+XmgK9CNmHXkho9qvmhdksdzDVsdeDlhK
IdcIWadhqDzdtn1hj/22iUwrhH0bd475hlKcsiZ+oy/sdgGgAzvmmTQmdMqEXqV2
B9q9KFBmo4Ahh/6+d4wM1rH9kxl0RvMAKLe+daoIHIjok8hCO4cKQQEw/ErBe4SF
2cr3wQwCfF1qVu4eAVNVfxfy/uEvG3Q7x005P3TcK+QcYgJxav3lictSi5dyWLgG
QAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7
VwIDAQAB
-----END PUBLIC KEY-----
n: ANnT_r0Z_io_kv6BnePZKuvgijQHbggta2i30x-wd6o5mWJuOcg5fl5oCvQjZh15IaPar5oXZLHcw1bHXg5YSiHXCFmnYag83bZ9YY_9tolMK4R9G3eO-YZSnLImfqMv7HYBoAM75pk0JnTKhF6ldgfavShQZqOAIYf-vneMDNax_ZMZdEbzACi3vnWqCByI6JPIQju
HCkEBMPxKwXuEhdnK98EMAnxdalbuHgFTVX8X8v7hLxt0O8dNOT903CvkHGICcWr95YnLUouXcli4BkAL5JJ1oraUSvClS8qRI-Vino-ghfJ6t9LrZ9eRUINCZB6Ks8Igqqnnp_BiD7XiO1c
它转换为以下配置(在高级 RabbitMQ 配置格式中)
auth_oauth2.resource_server_id = my_rabbit_server
auth_oauth2.signing_keys.a-key-ID = /path-to-signing-key-pem-file
如果使用对称密钥,则配置如下所示
[
{rabbitmq_auth_backend_oauth2, [
{resource_server_id, <<"my_rabbit_server">>},
{key_config, [
{signing_keys, #{
<<"a-key-ID">> => {map, #{<<"kty">> => <<"MAC">>,
<<"alg">> => <<"HS256">>,
<<"value">> => <<"my_signing_key">>}}
}}
]}
]},
].
为 scope 使用不同的令牌字段
该插件始终从 scope
声明中提取 scope。但是,您也可以配置插件以使用 auth_oauth2.additional_scopes_key
变量在其他声明中查找。
在 scope
声明中找到的 scope 必须是以下两种值类型
- 空格分隔的字符串,例如
my_id.configure:*/* my_id.read:*/* my_id.write:*/*
- 列表,例如
["my_id.configure:*/*", "my_id.read:*/*", "my_id.write:*/*"]
除了前面提到的 scope
声明支持的两种值类型之外,在 auth_oauth2.additional_scopes_key
变量中列出的任何声明中找到的 scope 可以是多种类型。
按 resource_server_id 索引的 scope 映射
这是一个令牌示例,其中 scope 尚未以 resource_server_id
为前缀,但已按 resource_server_id
索引
{
"exp": 1618592626,
"iat": 1618578226,
"aud" : ["my_id"],
...
"complex_claim_as_string": {
"rabbitmq": ["configure:*/* read:*/* write:*/*"]
},
"complex_claim_as_list": {
"rabbitmq": ["configure:vhost1/*", "read:vhost1/*", "write:vhost1/*"]
}
...
}
使用以下插件配置,插件从两个额外的声明中读取 scope:complex_claim_as_string
和 complex_claim_as_list
。插件读取 scope 并添加键值作为前缀。例如,给定 scope configure:*/*
,它会生成 rabbitmq.configure:*/*
。
auth_oauth2.resource_server_id = my_rabbit_server
auth_oauth2.additional_scopes_key = complex_claim_as_string complex_claim_as_list
深层嵌套在 Map 和 List 中的 Scope
这是 Keycloak 身份提供程序颁发的令牌的情况,但可以应用于来自任何提供程序的任何令牌。
第一个令牌格式将 scope 深层存储在 map 和 list 中。
{
"authorization": {
"permissions": [
{
"scopes": [
"rabbitmq-resource.read:*/*"
],
"rsid": "2c390fe4-02ad-41c7-98a2-cebb8c60ccf1",
"rsname": "allvhost"
},
{
"scopes": [
"rabbitmq-resource.write:vhost1/*"
],
"rsid": "e7f12e94-4c34-43d8-b2b1-c516af644cee",
"rsname": "vhost1"
},
{
"scopes": [
"rabbitmq-resource.tag:administrator"
],
"rsid": "12ac3d1c-28c2-4521-8e33-0952eff10bd9"
}
]
},
"scope": "email profile rabbitmq-resource.tag:monitoring",
}
给定以下配置
auth_oauth2.resource_server_id = my_rabbit_server
auth_oauth2.additional_scopes_key = authorization.permissions.scopes
插件按照以下逻辑导航令牌结构
- 它查找
authorization
声明。 - 它找到一个 map,然后查找下一个声明
permissions
。 - 这次,它找到一个 map 列表。它遍历列表中的所有项目。
- 对于列表中的每个 map,它查找下一个声明
scopes
。 - 该值可以是 scope 列表,也可以是逗号分隔的 scope 字符串,也可以是按 resource_server_id 索引的 scope 映射。
此外,插件始终从官方 scope
声明中读取 scope。
使用上述令牌和插件的配置,scope 列表如下
rabbitmq-resource.tag:monitoring
rabbitmq-resource.read:*/*
rabbitmq-resource.write:vhost1/*
rabbitmq-resource.tag:administrator
总而言之,插件能够导航令牌以使用适当的路径查找 scope。
例如,在找到 authorization
和/或 permissions
键后的每个中间阶段,该值可以是另一个 Map 或 Map 列表。在最后一个阶段,在找到最后一个 scopes
键后,该值可以是上一节中解释的任何值类型中的任何一种。
这些是
- 空格分隔的字符串,例如
my_id.configure:*/* my_id.read:*/* my_id.write:*/*
- 列表,例如
["my_id.configure:*/*", "my_id.read:*/*", "my_id.write:*/*"]
- 按资源服务器 id 索引的 Scope 映射
首选用户名声明
与令牌关联的用户名必须可用于 RabbitMQ,以便此用户名显示在 RabbitMQ 管理 UI 中。默认情况下,RabbitMQ 首先搜索 sub
声明,如果未找到,RabbitMQ 将使用 client_id
。
大多数授权服务器在 sub
声明中返回用户的 GUID,而不是用户的用户名或电子邮件地址,以及用户可以关联的任何内容。当 sub
声明未携带用户友好的用户名时,您可以配置一个或多个声明以从令牌中提取用户名。
示例 rabbitmq.conf
配置
# ...
auth_oauth2.resource_server_id = rabbitmq
auth_oauth2.preferred_username_claims.1 = user_name
auth_oauth2.preferred_username_claims.2 = email
# ...
在示例配置中,RabbitMQ 首先搜索 user_name
声明,如果未找到,RabbitMQ 将搜索 email
。如果这些都未找到,RabbitMQ 将使用其默认查找机制,该机制首先查找 sub
,然后查找 client_id
。
发现端点参数
某些 OAuth 2.0 提供程序需要在 OpenId Discovery 端点中添加某些查询参数。例如,当应用程序使用自定义签名密钥时,Microsoft Entra ID 需要一个名为 appid
的查询参数。发现端点返回针对与 appid
匹配的应用程序量身定制的 OpenId 配置。例如,OpenId 配置中返回的 jkws_uri
端点已具有发送到发现端点的查询参数。
以下是设置这些参数的示例,包括用于构建 OpenId 发现端点 URL 的其余变量。
# ...
auth_oauth2.issuer = https://myissuer.com/v2
auth_oauth2.discovery_endpoint_path = .well-known/authorization-server
auth_oauth2.discovery_endpoint_params.param1 = value1
auth_oauth2.discovery_endpoint_params.param2 = value2
# ...
这是构建的用于访问 OpenId 发现端点的 URL
https://myissuer.com/v2/.well-known/authorization-server?param1=value1¶m2=value2
请求方令牌
请求方令牌 (RPT) 是由 授权服务器 在 用户管理的访问 (UMA) 2.0 框架中颁发的特殊 OAuth 2.0 访问令牌。请求方(例如应用程序或用户)使用它在资源服务器(例如 RabbitMQ)上访问受保护的资源,在基于资源所有者策略获得授权后。
Keycloak 是颁发此类令牌的授权服务器之一。RPT 通常是 JWT,其权限声明位于名为 authorization
的声明下。请参见下面的示例。为了简洁起见,令牌中已删除其余声明
{
"authorization": {
"permissions": [
{
"scopes": [
"rabbitmq-resource.read:*/*"
],
"rsid": "2c390fe4-02ad-41c7-98a2-cebb8c60ccf1",
"rsname": "allvhost"
},
{
"scopes": [
"rabbitmq-resource:vhost1/*"
],
"rsid": "e7f12e94-4c34-43d8-b2b1-c516af644cee",
"rsname": "vhost1"
},
{
"rsid": "12ac3d1c-28c2-4521-8e33-0952eff10bd9",
"scopes": [
"rabbitmq-resource.tag:administrator"
]
}
]
},
"scope": "email profile",
}
RabbitMQ 支持此令牌格式。它读取所有 permissions
声明中的所有 scope。如果令牌还包含标准 scope
声明,RabbitMQ 会将其添加到令牌提供的 scope 列表中。
丰富授权请求
丰富授权请求扩展提供了一种 OAuth 客户端在授权请求期间请求细粒度权限的方法。它摆脱了作为文本标签的 scope 的概念,而是定义了更复杂的权限模型。
RabbitMQ 支持符合扩展的 JWT 令牌。以下是 JWT 令牌的示例部分
{
"authorization_details": [
{
"type" : "rabbitmq",
"locations": ["cluster:finance/vhost:production-*"],
"actions": [ "read", "write", "configure" ]
},
{
"type" : "rabbitmq",
"locations": ["cluster:finance", "cluster:inventory" ],
"actions": ["administrator" ]
}
]
}
上面的令牌在属性 authorization_details
下包含两个权限。这两个权限都用于 resource_server_type
设置为 rabbitmq
的 RabbitMQ 服务器。此字段标识 RabbitMQ 特定的权限。
第一个权限授予对任何虚拟主机上任何队列和/或交换机的 read
、write
和 configure
权限,这些虚拟主机的名称与模式 production-*
匹配,并且位于 resource_server_id
包含字符串 finance
的集群中。cluster
属性的值也是正则表达式。要完全匹配字符串 finance
,请使用 ^finance$
。
第二个权限授予两个集群(finance
和 inventory
)中的 administrator
用户标签。其他支持的用户标签包括 management
、policymaker
和 monitoring
。
类型字段
为了使 RabbitMQ 节点接受权限,其值必须与该节点的 resource_server_type
变量的值匹配。JWT 令牌可能具有多种资源类型的权限。
位置字段
locations
字段可以是包含单个位置的字符串,也可以是包含零个或多个位置的 Json 数组。
位置由正斜杠 /
字符分隔的键值对列表组成。以下是格式
cluster:<resource_server_id_pattern>[/vhost:<vhost_pattern>][/queue:<queue_name_pattern>|/exchange:<exchange_name_pattern>][/routing-key:<routing_key_pattern>]
任何由 /
分隔且不符合 <key>:<value>
的字符串都将被忽略。例如,如果您的位置以前缀开头,例如 vrn/cluster:rabbitmq
,则 vrn
模式部分将被忽略。
支持的位置属性为
cluster
:这是唯一必需的属性。它是一个通配符模式,必须与 RabbitMQ 的resource_server_id
匹配,否则该位置将被忽略。vhost
:这是您要授予访问权限的虚拟主机。它也是一个通配符模式。如果未指定,将使用*
。queue
|exchange
:队列或交换机名称模式。位置授予对一组与其匹配的队列(或交换机)的权限。一个位置只能指定queue
或exchange
,但不能同时指定两者。如果未指定,将使用*
routing-key
:这是位置授予权限的路由键模式。如果未指定,将使用*
有关通配符模式的更多信息,请查看Scope 到权限转换部分。
操作字段
actions
字段可以是包含单个操作的字符串,也可以是包含零个或多个操作的 Json 数组。
支持的操作映射到RabbitMQ 权限
configure
read
write
或 RabbitMQ 用户标签
administrator
monitoring
management
policymaker
丰富权限到 scope 转换
丰富授权请求权限将转换为 JWT 令牌 scope,这些 scope 使用上述约定和以下算法
对于在 locations
中找到的每个位置,其中 cluster
属性与当前 RabbitMQ 服务器的 resource_server_id
匹配
-
对于在
locations
字段中找到的每个位置,其中cluster
属性与当前 RabbitMQ 节点的resource_server_id
匹配,插件从位置中提取vhost
、queue
或exchange
和routing_key
属性。如果位置没有任何这些属性,则假定默认值为*
。在这些值中,将生成以下 scope 后缀scope_suffix = <vhost>/<queue>|<exchange>/<routing-key>
-
对于在
actions
字段中找到的每个操作如果操作不是已知的用户标签,则会从中生成以下 scope
scope = <resource_server_id>.<action>:<scope_suffix>
对于已知的用户标签操作,将生成以下 scope
scope = <resource_server_id>.<action>
插件生成所有 actions
与所有与节点配置的 resource_server_id
匹配的 locations
的排列组合。
在以下 RAR 示例中
{
"authorization_details": [
{ "type" : "rabbitmq",
"locations": ["cluster:finance/vhost:primary-*"],
"actions": [ "read", "write", "configure" ]
},
{ "type" : "rabbitmq",
"locations": ["cluster:finance", "cluster:inventory" ],
"actions": ["administrator" ]
}
]
}
如果 RabbitMQ 节点 resource_server_id
等于 finance
,则插件会计算以下 scope 集
finance.read:primary-*/*/*
finance.write:primary-*/*/*
finance.configure:primary-*/*/*
finance.tag:administrator
高级用法
使用默认 OAuth 2.0 提供程序
只要您只有一个 OAuth 2.0 提供程序,您就可以跳过此高级用法,尽管您可以使用它。
在基本用法部分下,您配置了 issuer
url,或者可能配置了 jwks_uri
以及所需的 TLS 变量。此高级用法将配置所有与 OAuth 提供程序相关的专用配置。
以下是使用 issuer
配置身份提供程序 URL 的示例配置
auth_oauth2.resource_server_id = rabbitmq-prod
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.issuer = https://prodkeycloak:8080/realm/prod
auth_oauth2.https.cacertfile = /opts/certs/prodcacert.pem
在 auth_oauth2.oauth_providers
变量下配置身份提供程序的等效配置是
auth_oauth2.resource_server_id = rabbitmq-prod
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.default_oauth_provider = prodkeycloak
auth_oauth2.oauth_providers.prodkeycloak.issuer = https://prodkeycloak:8080/realm/prod
auth_oauth2.oauth_providers.prodkeycloak.https.cacertfile = /opts/certs/prodcacert.pem
当用户提供由不同的 OAuth 2.0 提供程序颁发或签名的令牌时,后一种配置更相关。但是,如果设置了 auth_oauth2.default_oauth_provider
,仍然可以使用它。
配置 OAuth 2.0 提供程序的 end_session_endpoint
只有当 OpenId Connect Discovery 端点 未返回 end_session_endpoint
并且您想要单点注销功能时,才需要此高级设置。换句话说,当用户从管理 UI 注销时,也会从 OAuth 提供程序注销。
如果 OpenId Connect Discovery 端点 响应确实包含 end_session_endpoint
,则管理 UI 将使用它而不是配置的端点。
以下是设置 end_session_endpoint
的示例配置
auth_oauth2.resource_server_id = rabbitmq-prod
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.issuer = https://prodkeycloak:8080/realm/prod
auth_oauth2.end_session_endpoint = https://prodkeycloak:8080/realm/prod/logout
在 auth_oauth2.oauth_providers
变量下配置身份提供程序的等效配置是
auth_oauth2.resource_server_id = rabbitmq-prod
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.default_oauth_provider = prodkeycloak
auth_oauth2.oauth_providers.prodkeycloak.issuer = https://prodkeycloak:8080/realm/prod
auth_oauth2.oauth_providers.prodkeycloak.end_session_endpoint = https://prodkeycloak:8080/realm/prod/logout
配置多个资源服务器
通常,访问 RabbitMQ 集群的所有用户都在同一个身份提供程序中注册。同样,所有以同一 RabbitMQ 集群为目标的令牌也携带相同的受众。换句话说,所有用户都使用相同的资源名称引用 RabbitMQ 集群,该名称必须与 auth_oauth2.resource_server_id
变量的值匹配。
但是,在某些用例中,RabbitMQ 由在不同身份提供程序中注册的用户访问,或者为同一 RabbitMQ 安装颁发令牌,但具有不同的受众。对于这些用例,可以使用多个 OAuth 2.0 资源配置 RabbitMQ OAuth 2.0 插件和管理插件。
以下是 OAuth 2.0 插件配置,用于具有 id 的两个资源:rabbit_prod
和 rabbit_dev
。两个资源(也称为受众)都由同一身份提供程序管理,该提供程序的颁发者为 http//some_idp_url
。
auth_oauth2.issuer = http//some_idp_url
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.resource_servers.1.id = rabbit_prod
auth_oauth2.resource_servers.2.id = rabbit_dev
auth_oauth2.resource_servers.2.scope_prefix = dev-rabbitmq.
到目前为止,所有资源服务器都共享您在 auth_oauth2.
下设置的变量,例如 scope_prefix
。但是,它们可以覆盖它们。以下是资源服务器可以覆盖的变量列表
-
id
- 这是令牌的audience
字段中携带的实际资源标识符。如果省略,则该值为索引,例如,给定auth_oauth2.resource_servers.prod.scope_prefix
变量,则id
将为prod
。 -
scope_prefix
-
additional_scopes_key
-
resource_server_type
-
oauth_provider_id
- 这是 OAuth 提供程序的标识符。它在 RabbitMQ 中配置。它提供了所有变量来联系授权服务器并发现其所有端点,例如jwks_uri
以下载签名密钥以验证令牌。如果省略此变量,RabbitMQ 将在变量
auth_oauth2.default_oauth_provider
中查找默认授权提供程序的 id,如果也省略了该变量,RabbitMQ 将使用auth_oauth2.issuer
或auth_oauth2.jwks_uri
下载签名密钥以验证令牌。
支持的资源服务器列表是 auth_oauth2.resource_servers
和 auth_oauth2.resource_server_id
的组合。您可以同时使用两者或仅使用其中之一。
有一个示例演示如何使用多个 OAuth 2 资源。
在单独的部分中记录了每个 OAuth 提供程序的所有可配置变量列表。
配置多个 OAuth 2.0 提供程序
只有在配置了多个资源时,设置多个 OAuth 2.0 提供程序才有意义。
这是上一节中使用的配置,但已修改为使用多个 OAuth 2.0 提供程序
auth_oauth2.scope_prefix = rabbitmq.
auth_oauth2.resource_servers.1.id = rabbit_prod
auth_oauth2.resource_servers.1.oauth_provider_id = prod
auth_oauth2.resource_servers.2.id = rabbit_dev
auth_oauth2.resource_servers.2.oauth_provider_id = dev
auth_oauth2.resource_servers.2.scope_prefix = dev-rabbitmq.
auth_oauth2.oauth_providers.prod.issuer = https://rabbit_prod:8080
auth_oauth2.oauth_providers.prod.https.cacertfile = /opts/certs/prod.pem
auth_oauth2.oauth_providers.dev.issuer = https://rabbit_dev:8080
auth_oauth2.oauth_providers.dev.https.cacertfile = /opts/certs/dev.pem
在单独的部分中记录了每个 OAuth 提供程序的所有可配置变量列表。
示例
RabbitMQ OAuth 2.0 身份验证后端示例包含许多示例配置文件,可用于设置多个 OAuth 2.0 提供程序,包括 UAA、Auth0 和 Azure,并颁发令牌,这些令牌可用于访问 RabbitMQ 资源。