跳至主要内容
版本:4.0

使用多个 OAuth 2.0 服务器和/或受众

本指南介绍如何为 RabbitMQ 和多个 OAuth 资源设置 OAuth 2.0,并使用以下流程

  • 应用程序身份验证和授权
  • 访问 管理 UI

先决条件

  • Docker
  • 本地克隆的 GitHub 存储库,其中包含本示例中使用的所有配置文件和脚本

单个 OAuth 2.0 与多个 OAuth 2.0 资源

到目前为止,除了本示例之外,所有其他示例都配置了单个 resource_server_id,因此也配置了单个 OAuth 2.0 服务器

在某些情况下,一些管理用户和/或应用程序在不同的 OAuth 2 服务器中注册,或者它们可能在同一 OAuth 2 服务器中注册,但使用不同的受众值引用 RabbitMQ。为了支持这种情况,必须声明尽可能多的 OAuth 2 资源作为受众和/或授权服务器。

以下三种场景演示了您可能会遇到的各种配置

场景 1:消息传递 (AMQP) 客户端和管理用户注册在同一个 OAuth 2.0 服务器中,但使用不同的受众

RabbitMQ 配置了两个 OAuth2 资源,一个名为 rabbit_prod,另一个名为 rabbit_dev。例如,假设生产团队使用 rabbit_prod 受众引用 RabbitMQ。而开发团队使用 rabbit_dev 受众。由于这两个团队都注册在同一个 OAuth2 服务器中,因此您将在根级别配置其设置(如 issuer),以便这两个资源共享相同的配置。

测试应用程序使用其自己的受众访问 AMQP 协议

这是配置的摘要,可在 rabbitmq.scenario1.conf 中找到

在 Keycloak 中声明了两个 OAuth2 客户端(prod_producerdev_producer),并配置为访问其各自的受众:rabbit_prodrabbit_dev。RabbitMQ OAuth 2 插件配置如下

  • 有两个资源:rabbit_prodrabbit_dev
auth_oauth2.resource_servers.1.id = rabbit_prod
auth_oauth2.resource_servers.2.id = rabbit_dev
  • 这两个资源的公共设置
auth_oauth2.preferred_username_claims.1 = preferred_username
auth_oauth2.preferred_username_claims.2 = user_name
auth_oauth2.preferred_username_claims.3 = email
auth_oauth2.scope_prefix = rabbitmq.
  • 一个 OAuth 提供程序
auth_oauth2.oauth_providers.keycloak.issuer = https://keycloak:8443/realms/test
auth_oauth2.oauth_providers.keycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem
auth_oauth2.oauth_providers.keycloak.https.verify = verify_peer
auth_oauth2.oauth_providers.keycloak.https.hostname_verification = wildcard
auth_oauth2.default_oauth_provider = keycloak

按照以下步骤部署 Keycloak 和 RabbitMQ

  1. 启动 Keycloak。使用凭据 admin:admin 检查 管理页面

    make start-keycloak
    提示

    建议关注日志,直到 keycloak 完全初始化:docker logs keycloak -f

  2. 使用 rabbitmq.scenario1.conf 启动 RabbitMQ

    MODE="multi-keycloak" CONF="rabbitmq.scenario1.conf" make start-rabbitmq
  3. 启动在 Keycloak 中注册的 AMQP 生产者,其 client_idprod_producer,并具有访问 rabbit_prod 资源的权限,以及 rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* 范围

    make start-perftest-producer-with-token PRODUCER=prod_producer TOKEN=$(bin/keycloak/token prod_producer PdLHb1w8RH1oD5bpppgy8OF9G6QeRpL9)

    这是为 prod_producer 生成的访问令牌。

    {
    "exp": 1690974839,
    "iat": 1690974539,
    "jti": "c8edec50-5f29-4bd0-b25b-d7a46dc3474e",
    "iss": "https://127.0.0.1:8081/realms/test",
    "aud": "rabbit_prod",
    "sub": "826065e7-bb58-4b65-bbf7-8982d6cca6c8",
    "typ": "Bearer",
    "azp": "prod_producer",
    "acr": "1",
    "realm_access": {
    "roles": [
    "default-roles-test",
    "offline_access",
    "producer",
    "uma_authorization"
    ]
    },
    "resource_access": {
    "account": {
    "roles": [
    "manage-account",
    "manage-account-links",
    "view-profile"
    ]
    }
    },
    "scope": "profile email rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*",
    "clientId": "prod_producer",
    "clientHost": "172.18.0.1",
    "email_verified": false,
    "preferred_username": "service-account-prod_producer",
    "clientAddress": "172.18.0.1"
    }
  4. 类似地,启动 AMQP 生产者 dev_producer,也在 Keycloak 中注册,但具有访问 rabbit_dev 资源的权限

    make start-perftest-producer-with-token PRODUCER=dev_producer TOKEN=$(bin/keycloak/token dev_producer z1PNm47wfWyulTnAaDOf1AggTy3MxX2H)

测试通过两个单独的资源访问的管理 UI

这是启用管理 UI 中的 OAuth 2.0 的配置摘要

  • 在 Keycloak 中声明了两个用户:prod_userdev_user

  • 这两个资源 rabbit_prodrabbit_dev 在 RabbitMQ 管理插件中声明,每个资源都有自己的 OAuth 2 客户端(rabbit_prod_mgt_uirabbit_dev_mgt_ui)范围,以及与每个资源关联的标签

    management.oauth_resource_servers.1.id = rabbit_prod
    management.oauth_resource_servers.1.client_id = rabbit_prod_mgt_ui
    management.oauth_resource_servers.1.label = RabbitMQ Production
    management.oauth_resource_servers.1.scopes = openid profile rabbitmq.tag:administrator

    management.oauth_resource_servers.2.id = rabbit_dev
    management.oauth_resource_servers.2.client_id = rabbit_dev_mgt_ui
    management.oauth_resource_servers.2.label = RabbitMQ Development
    management.oauth_resource_servers.2.scopes = openid profile rabbitmq.tag:management
    注意

    由于只有一个 OAuth2 服务器,因此这两个资源共享名为 keycloak 的 OAuth 提供程序。

  • 每个 OAuth2 客户端 rabbit_prod_mgt_uirabbit_dev_mgt_ui 都在 Keycloak 中声明,以便它们只能为其各自的受众发出令牌,无论是 rabbit_prod 还是 rabbit_dev

按照以下步骤执行使用两个 OAuth 资源的管理 UI 流程

  1. 转到 RabbitMQ 管理 UI
  2. 选择 RabbitMQ Production 资源。
  3. prod_user:prod_user 登录。
  4. Keycloak 会提示您授权 prod_user 的各种范围。
  5. 您现在应该会重定向到管理 UI,作为 prod_user 用户。

现在,注销并对 dev_user 用户重复相同的步骤。对于此用户,RabbitMQ 配置为仅请求 rabbitmq.tag:management 范围。

警告

在步骤 3 中,如果您以 dev_user 登录,RabbitMQ 将不会授权 dev_user,因为 RabbitMQ 配置为请求 RabbitMQ Production 的范围:rabbitmq.tag:administrator

dev_user 没有 rabbitmq.tag:administrator 范围,它具有 rabbitmq.tag:management 范围。在这种情况下,dev_user 获取的令牌不包含 RabbitMQ 支持的任何范围。

场景 2:在多个 OAuth 提供程序下,两个 OAuth 2 资源位于专用 Realm 中

此场景使用名为 keycloak 的相同 OAuth 2.0 提供程序,但是,这次有两个 Realm,devprod

  • 在 Realm dev 下,有用户和客户端被授予对 rabbit_dev 资源的访问权限
    • dev_producer(密码:SBuw1L5a7Y2aQfWfbsgXlEKGTNaEHxO8)。
    • rabbit_dev_admin(密码:rabbit_dev_admin)。
    • rabbit_dev_mgt_api.
  • 在 Realm prod 下,有用户和客户端被授予对 rabbit_prod 资源的访问权限
    • prod_producer,其受众为 rabbit_prod(密码:PdLHb1w8RH1oD5bpppgy8OF9G6QeRpL9)。
    • rabbit_prod_admin(密码:rabbit_prod_admin)。

尽管只有一个物理 OAuth 提供程序,但您需要使用两个 OAuth 2.0 提供程序配置 RabbitMQ。每个租户都有自己的 issuer URL。用于此场景的配置文件为 rabbitmq.scenario2.conf。为了方便起见,以下是相关部分

...
## Oauth providers
auth_oauth2.oauth_providers.devkeycloak.issuer = https://keycloak:8443/realms/dev
auth_oauth2.oauth_providers.devkeycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem
auth_oauth2.oauth_providers.devkeycloak.https.verify = verify_peer
auth_oauth2.oauth_providers.devkeycloak.https.hostname_verification = wildcard

auth_oauth2.oauth_providers.prodkeycloak.issuer = https://keycloak:8443/realms/prod
auth_oauth2.oauth_providers.prodkeycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem
auth_oauth2.oauth_providers.prodkeycloak.https.verify = verify_peer
auth_oauth2.oauth_providers.prodkeycloak.https.hostname_verification = wildcard

...

按照以下步骤部署 Keycloak 和 RabbitMQ

  1. 启动 Keycloak。
make start-keycloak
提示

运行 docker ps | grep keycloak 以检查实例何时启动。建议关注日志,直到两个实例都完全初始化:docker logs keycloak -f

  1. 启动 RabbitMQ。
MODE=multi-keycloak OAUTH_PROVIDER=keycloak CONF=rabbitmq.scenario2.conf make start-rabbitmq
  1. 启动在 Keycloak 中注册的 AMQP 生产者,其 client_idprod_producer,并具有访问 rabbit_prod 资源的权限,以及 rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* 范围
make start-perftest-producer-with-token PRODUCER=prod_producer TOKEN=$(bin/keycloak/token prod_producer sIqZ5flmSz3r6uKXMSz8CWGeScdTpqq0 prod)
  1. 启动在 Keycloak 中注册的 AMQP 生产者,其 client_iddev_producer,并具有访问 rabbit_dev 资源的权限,以及 rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* 范围
make start-perftest-producer-with-token PRODUCER=dev_producer TOKEN=$(bin/keycloak/token dev_producer SBuw1L5a7Y2aQfWfbsgXlEKGTNaEHxO8 dev)
  1. 停止这两个生产者
make stop-perftest-producer PRODUCER=dev_producer
make stop-perftest-producer PRODUCER=prod_producer
  1. 验证 rabbit_dev_mgt_api 是否可以访问管理 API,因为其令牌授予对 rabbit_dev 的访问权限
make curl-keycloak url=https://127.0.0.1:15672/api/overview client_id=rabbit_dev_mgt_api secret=La1Mvj7Qvt8iAqHisZyAguEE8rUpg014 realm=dev

您应该在标准输出中看到与 RabbitMQ 管理 API 中的端点 /overview 对应的 JSON 块。

  1. 验证 mgt_api_client 是否无法访问管理 API,因为其令牌未授予对 rabbit_devrabbit_prod 的访问权限
make curl-keycloak url=https://127.0.0.1:15672/api/overview client_id=mgt_api_client secret=La1Mvj7Qvt8iAqHisZyAguEE8rUpg014 realm=test

您应该在标准输出中看到以下内容

{"error":"not_authorized","reason":"Not_Authorized"}
  1. 验证管理 UI 访问权限

    • 转到 https://127.0.0.1:15672
    • 选择“RabbitMQ Development”OAuth 2.0 资源。
    • 单击“单击此处登录”。
    • 使用 rabbit_dev_admin / rabbit_dev_admin 对 Keycloak 进行身份验证。
    • 验证用户是否被重定向到管理 UI。
    • 单击“注销”。
    • 使用“RabbitMQ Production”和用户 rabbit_prod_admin / rabbit_prod_admin 重复此操作。
  2. 关闭 RabbitMQ 和 Keycloak

make stop-keycloak
make stop-rabbitmq

场景 3:两个 OAuth 2 资源在独立的 OAuth 2 提供程序上

此场景使用两个独立的 OAuth 2.0 提供程序,分别称为 devkeycloakprodkeycloak,并具有以下设置

  • devkeycloakdev Realm 下具有以下设置,并授予对 rabbit_dev 资源的访问权限
    • dev_producer,其受众为 rabbit_dev(密码:SBuw1L5a7Y2aQfWfbsgXlEKGTNaEHxO8)。
    • rabbit_dev_admin(密码:rabbit_dev_admin)。
    • rabbit_dev_mgt_api.
  • prodkeycloakprod Realm 下具有以下设置,并授予对 rabbit_prod 资源的访问权限
    • prod_producer,其受众为 rabbit_prod(密码:PdLHb1w8RH1oD5bpppgy8OF9G6QeRpL9)。
    • rabbit_prod_admin(密码:rabbit_prod_admin)。

查看配置文件中 oauth_providers 部分rabbitmq.scenario3.conf,该文件由此场景使用。与场景 2 类似,有两个 OAuth 提供程序,但是这次 URL 指向两个不同的主机名。为了方便起见,以下是相关部分

...

## Oauth providers
auth_oauth2.oauth_providers.devkeycloak.issuer = https://devkeycloak:8443/realms/dev
auth_oauth2.oauth_providers.devkeycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem
auth_oauth2.oauth_providers.devkeycloak.https.verify = verify_peer
auth_oauth2.oauth_providers.devkeycloak.https.hostname_verification = wildcard

auth_oauth2.oauth_providers.prodkeycloak.issuer = https://prodkeycloak:8442/realms/prod
auth_oauth2.oauth_providers.prodkeycloak.https.cacertfile = /etc/rabbitmq/keycloak-ca_certificate.pem
auth_oauth2.oauth_providers.prodkeycloak.https.verify = verify_peer
auth_oauth2.oauth_providers.prodkeycloak.https.hostname_verification = wildcard

...

请按照以下步骤部署两个 Keycloak 和 RabbitMQ

  1. 启动 Keycloak。
make start-dev-keycloak
make start-prod-keycloak
提示

运行 docker ps | grep keycloak 以查看两个实例是否已启动。

  1. 启动 RabbitMQ。
MODE=multi-keycloak CONF=rabbitmq.scenario3.conf make start-rabbitmq
  1. 启动在 Keycloak 中注册的 AMQP 生产者,其 client_idprod_producer,并具有访问 rabbit_prod 资源的权限,以及 rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* 范围
make start-perftest-producer-with-token PRODUCER=prod_producer TOKEN=$(bin/prodkeycloak/token prod_producer PdLHb1w8RH1oD5bpppgy8OF9G6QeRpL9)
  1. 启动在 Keycloak 中注册的 AMQP 生产者,其 client_iddev_producer,并具有访问 rabbit_dev 资源的权限,以及 rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* 范围
make start-perftest-producer-with-token PRODUCER=dev_producer TOKEN=$(bin/devkeycloak/token dev_producer z1PNm47wfWyulTnAaDOf1AggTy3MxX2H)
  1. 停止这两个生产者
make stop-perftest-producer PRODUCER=dev_producer
make stop-perftest-producer PRODUCER=prod_producer
  1. 验证 rabbit_dev_mgt_api 是否可以访问管理 API,因为其令牌授予对 rabbit_dev 的访问权限
make curl-dev-keycloak url=https://127.0.0.1:15672/api/overview client_id=rabbit_dev_mgt_api secret=p7v6DksWkcb6TUYK6payswovC0LqhU6A

您应该在标准输出中看到与 RabbitMQ 管理 API 中的端点 /overview 对应的 JSON 块。

  1. 验证 mgt_api_client 是否无法访问管理 API,因为其令牌未授予对 rabbit_devrabbit_prod 的访问权限
make curl-keycloak url=https://127.0.0.1:15672/api/overview client_id=mgt_api_client secret=La1Mvj7Qvt8iAqHisZyAguEE8rUpg014 realm=test

您应该在标准输出中看到以下内容

{"error":"not_authorized","reason":"Not_Authorized"}
  1. 验证管理 UI 访问权限

    • 转到 https://127.0.0.1:15672
    • 选择“RabbitMQ Development”OAuth 2.0 资源。
    • 单击“单击此处登录”。
    • 使用 rabbit_dev_admin / rabbit_dev_admin 对 Keycloak 进行身份验证。
    • 验证用户是否被重定向到管理 UI。
    • 单击“注销”。
    • 使用“RabbitMQ Production”和用户 rabbit_prod_admin / rabbit_prod_admin 重复此操作。
  2. 关闭 RabbitMQ 和两个 Keycloak

make stop-dev-keycloak
make stop-prod-keycloak
make stop-rabbitmq
© 2024 RabbitMQ. All rights reserved.