Amazon MQ for RabbitMQ 支持IAM OAuth 2.0认证
DataHot 速览
AWS 官方博客介绍了 Amazon MQ for RabbitMQ 通过 OAuth 2.0 集成 IAM 认证的方案,可消除静态凭据管理负担。文章说明客户端使用现有 IAM 身份获取短时 JWT 完成认证,访问控制集中在 IAM 角色和代理配置中。还演示了基于租户级 IAM 角色与 RabbitMQ scope alias 实现 vhost 级隔离的多租户用例。该功能要求 RabbitMQ 3.13 和 4.2 及以上版本。
为什么值得关注:面向数据平台工程师的认证与权限治理实践,展示如何用 IAM 替代静态凭据,提升多租户数据接入的安全性。
本文目录 16 节
译文
AI 逐段翻译这是关于 Amazon MQ for RabbitMQ 的身份验证和授权的三部分系列文章的第三部分。有关所有可用方法的概述,请参阅Amazon MQ for RabbitMQ 的身份验证和授权选项。有关基于证书的 mTLS 和 SSL 身份验证,请参阅第 1 部分。有关 OAuth 2.0、LDAP、Entra ID 和 HTTP 身份验证,请参阅第 2 部分。
当您在没有AWS Identity and Access Management (IAM)身份验证的情况下大规模运行Amazon MQ for RabbitMQ时,您会面临一个常见挑战:在多个服务之间管理静态凭据,每个服务都需要自己的用户名和密码。这种方法通过密码轮换、凭据分发以及意外泄露机密的风险带来了运营开销。使用 OAuth 2.0 的 IAM 身份验证消除了这些静态凭据。客户端改用其现有 IAM 身份进行身份验证。
本文介绍了使用 IAM 作为 OAuth 2.0 提供程序的关键配置选项,并演示了通过 IAM 角色和代理级作用域别名强制实施 vhost 级隔离的多租户用例。
Amazon MQ for RabbitMQ 通过 OAuth 2.0 支持基于 IAM 的身份验证,因此您可以进行集中访问控制,而无需管理代理本地凭据。客户端使用其现有 IAM 身份进行身份验证。令牌自动过期,访问控制完全存在于 IAM 角色和代理配置中。
注意:Amazon MQ for RabbitMQ 的 IAM 身份验证需要 RabbitMQ 3.13 和 4.2 或更高版本。Amazon MQ for ActiveMQ 代理不支持此功能。
重要:在代理上启用 IAM 身份验证之前,必须在您的 AWS 账户中配置并可用的 IAM 出站联合。
概述
本文涵盖 Amazon MQ for RabbitMQ 基于 IAM 的身份验证的两个方面:
- IAM 作为 OAuth 2.0 身份提供程序:Amazon MQ 如何使用 IAM 出站联合和 RabbitMQ OAuth 2.0 插件,通过AWS Security Token Service (AWS STS)颁发的短期 JSON Web 令牌 (JWT) 对客户端进行身份验证,从而消除代理本地凭据。
- 使用 IAM 角色和作用域别名实现多租户隔离:每个租户的 IAM 角色与 RabbitMQ 作用域别名相结合,如何限制对特定虚拟主机(vhost)的访问,从而在身份验证层和代理层强制实施租户隔离。
这两种能力共同作用,通过AWS CloudTrail提供无凭据身份验证、集中访问控制和全面的审计跟踪。
IAM 身份验证的工作原理
Amazon MQ for RabbitMQ 的 IAM 身份验证使用 RabbitMQ OAuth 2.0 插件,通过 IAM 出站联合将 IAM 作为身份提供程序。客户端无需在代理中管理用户名和密码,而是使用 AWS STS 颁发的短期 JWT 进行身份验证。
当客户端连接到配置了 IAM 身份验证的代理时:
- 客户端应用程序使用其 IAM 凭据(来自其 AWS Lambda 函数、Amazon Elastic Container Service (Amazon ECS) 任务、Amazon Elastic Kubernetes Service (Amazon EKS) 或 Amazon Elastic Compute Cloud (Amazon EC2) 实例所附加的 IAM 角色)调用 AWS STS。
- AWS STS 评估调用者的 IAM 策略,以确定是否允许
sts:GetWebIdentityToken。 - 如果策略允许该请求,AWS STS 将颁发一个签名的 JWT,其中编码了调用者的身份和允许的 RabbitMQ 作用域。
- 客户端连接到 Amazon MQ 代理,并将 JWT 作为 OAuth 2.0 不记名令牌(作为密码传递)提交。
- 代理通过 JSON Web Key Set (JWKS) 端点检索 AWS STS 公共密钥,并验证令牌签名、过期时间和受众声明。
- 代理从令牌的
sub声明中提取调用者的 IAM 角色 ARN,将其与配置的作用域别名进行匹配,并授予相应的 RabbitMQ 权限。
下图显示了 IAM 身份验证流程。

与传统用户名/密码身份验证相比的优势
下表在规模化运营中最重要的操作维度上比较了传统用户名/密码身份验证与基于 IAM 的 OAuth 2.0 身份验证。
| 方面 | 传统(用户名/密码) | 基于 IAM(OAuth 2.0 JWT) |
| 凭据管理 | 手动创建、分发和轮换 | 通过 IAM 角色自动管理。无代理本地凭据 |
| 凭据生命周期 | 静态,直到手动轮换 | 短期(5 分钟至 1 小时)。自动过期 |
| 访问控制 | 每个用户的代理本地权限 | 通过 IAM 角色映射到代理作用域别名实现集中化 |
| 审计跟踪 | 仅代理日志 | AWS CloudTrail 记录每次令牌颁发和策略评估 |
| 租户隔离 | 每个用户手动配置权限 | 按角色作用域别名在代理上强制实施 vhost 限制 |
| 上线/下线 | 创建/删除 RabbitMQ 用户并分发凭据 | 创建/删除 IAM 角色。无需分发凭据 |
关键配置
以下 rabbitmq.conf 片段显示了基于 IAM 的 OAuth 2.0 身份验证的基本设置:
# Enable OAuth 2.0 authentication with IAM, with internal as fallback
auth_backends.1 = oauth2
auth_backends.2 = internal
# Token validation - account-specific JWKS endpoint
auth_oauth2.jwks_uri = https://<issuer-id>.tokens.sts.global.api.aws/.well-known/jwks.json
auth_oauth2.https.hostname_verification = wildcard
# Resource server configuration
auth_oauth2.resource_server_id = rabbitmq
auth_oauth2.scope_prefix = rabbitmq/
# Required: extract identity from the 'sub' claim in STS JWTs
auth_oauth2.additional_scopes_key = sub
# Scope alias maps IAM role ARN to RabbitMQ permissions
auth_oauth2.scope_aliases.1.alias = arn:aws:iam::<account-id>:role/RabbitMqAdminRole
auth_oauth2.scope_aliases.1.scope = rabbitmq/tag:administrator rabbitmq/read:*/* rabbitmq/write:*/* rabbitmq/configure:*/*
# Enable OAuth for the Management UI
management.oauth_enabled = true注意: auth_oauth2.jwks_uri 值特定于账户。通过运行aws iam enable-outbound-web-identity-federation获取,该命令返回一个签发者标识符 URL。附加/.well-known/jwks.json以形成完整的 JWKS URI。
下表描述了上述片段中显示的每个配置设置。
| 设置 | 用途 |
| auth_backends.1 = oauth2 | 启用 OAuth 2.0 身份验证后端 |
| auth_backends.2 = internal | 回退到内部身份验证以支持系统监控用户 |
| auth_oauth2.jwks_uri | 特定账户的 JWKS 端点(来自 IAM 出站联合),用于验证令牌签名 |
| auth_oauth2.resource_server_id | 将此代理标识为资源服务器。必须与请求令牌时使用的--audience值匹配 |
| auth_oauth2.scope_prefix | 应用于作用域值的前缀(例如 rabbitmq/) |
| auth_oauth2.additional_scopes_key | JWT 声明键,RabbitMQ 在其中查找用于作用域别名匹配的身份(对于 STS JWT,必须为sub) |
| auth_oauth2.scope_aliases..alias | 映射到一组RabbitMQ权限的IAM角色ARN |
| auth_oauth2.scope_aliases..scope | 当别名匹配时授予的RabbitMQ权限 |
| auth_oauth2.https.hostname_verification | 为AWS STS端点证书验证设置为通配符 |
| management.oauth_enabled | 为管理API/UI启用OAuth令牌认证 |
具有vhost限制的IAM策略
IAM策略条件是认证层强制租户隔离的关键。以下策略限制角色只能请求特定vhost范围内的令牌:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:GetWebIdentityToken",
"sts:TagGetWebIdentityToken"
],
"Resource": "*"
}
]
}| 策略元素 | 用途 |
| sts:GetWebIdentityToken | 授权通过STS签发JWT令牌 |
| sts:TagGetWebIdentityToken | 允许向令牌请求附加请求标签(如scope) |
vhost级别的隔离通过scope别名在代理层强制执行(参见下文“使用IAM进行多租户隔离”部分),而非通过IAM策略条件。每个IAM角色通过代理配置映射到一组特定的RabbitMQ权限,代理拒绝任何与匹配的scope别名不匹配的访问。
重要注意事项
- IAM认证在Amazon MQ for RabbitMQ版本3.13和4.2或更高版本上受支持。它在Amazon MQ for ActiveMQ代理上不受支持。
- IAM认证要求在您的AWS账户中配置并可用IAM出站联合。在配置基于IAM的认证之前,请确保出站联合已启用。
- 使用AWS STS,您可以通过
--duration-seconds参数请求持续时间在300秒(5分钟)到3600秒(1小时)之间的web身份令牌。在客户端应用程序中实现令牌缓存和刷新逻辑,以避免每次连接都请求新令牌。 - 不要将IAM用户凭据嵌入应用程序代码或环境变量中。将IAM角色附加到AWS Lambda函数、Amazon ECS任务、Amazon EKS pod或Amazon EC2实例,以便凭据由AWS运行时自动签发和轮换。
- IAM策略评估在任何代理交互之前进行。如果策略拒绝
sts:GetWebIdentityToken请求,AWS STS返回AccessDenied,并且不会尝试连接。 - Amazon MQ自动创建一个名为monitoring-AWS-OWNED-DO-NOT-DELETE的系统用户,具有仅监控权限。此用户即使在启用IAM的代理上也使用RabbitMQ的内部认证系统,Amazon MQ将其限制为仅回环接口访问。
限制
- 范围声明配置:您不能直接使用范围声明,因为来自AWS STS的JWT令牌将调用者身份(IAM角色ARN)放在
sub声明中,而不是标准的scope声明。这要求设置auth_oauth2.additional_scopes_key = sub并在RabbitMQ配置中使用scope别名将IAM角色ARN映射到RabbitMQ权限。此限制还阻止完全使用IAM策略进行授权,而需要在RabbitMQ配置中进行授权。
有关如何为您的Amazon MQ for RabbitMQ代理配置IAM认证和授权的信息,请参阅以下“实施指南”部分。
使用IAM进行多租户隔离
基于IAM的认证对于多租户架构特别有效,您需要在共享RabbitMQ基础设施中强制数据隔离。通过将每个租户的IAM角色与RabbitMQ scope别名结合,您在三个层面强制隔离:
- IAM层:信任策略限制哪些主体(Lambda函数、ECS任务、EKS pod)可以承担每个租户的IAM角色。属于租户A的服务不能承担租户B的角色。
- 代理层:Scope别名确保每个角色ARN仅为自己的vhost获得权限。即使客户端尝试连接到不同的vhost,代理也会拒绝访问,因为令牌的
sub声明仅映射到不同vhost的权限。 - 审计层:CloudTrail记录每次角色承担和AWS STS令牌请求,包括IAM主体以及请求被授予还是拒绝。
下图显示了多租户架构。

用于多租户隔离的代理配置
仅AMQP访问(默认): 对于通过AMQP连接以生产和消费消息的租户:
# Tenant A - AMQP access to tenant-a vhost only
auth_oauth2.scope_aliases.2.alias = arn:aws:iam::<account-id>:role/TenantARole
auth_oauth2.scope_aliases.2.scope = rabbitmq/configure:tenant-a/* rabbitmq/write:tenant-a/* rabbitmq/read:tenant-a/*
# Tenant B - AMQP access to tenant-b vhost only
auth_oauth2.scope_aliases.3.alias = arn:aws:iam::<account-id>:role/TenantBRole
auth_oauth2.scope_aliases.3.scope = rabbitmq/configure:tenant-b/* rabbitmq/write:tenant-b/* rabbitmq/read:tenant-b/*具有管理API访问(可选): 对于还需要HTTP API访问以进行监控或管理的租户:
# Tenant A - AMQP + Management API access to tenant-a vhost
auth_oauth2.scope_aliases.2.alias = arn:aws:iam::<account-id>:role/TenantARole
auth_oauth2.scope_aliases.2.scope = rabbitmq/tag:management rabbitmq/configure:tenant-a/* rabbitmq/write:tenant-a/* rabbitmq/read:tenant-a/*
# Tenant B - AMQP + Management API access to tenant-b vhost
auth_oauth2.scope_aliases.3.alias = arn:aws:iam::<account-id>:role/TenantBRole
auth_oauth2.scope_aliases.3.scope = rabbitmq/tag:management rabbitmq/configure:tenant-b/* rabbitmq/write:tenant-b/* rabbitmq/read:tenant-b/* tag:management范围授予访问RabbitMQ管理HTTP API的权限,限于租户已有权限的资源。大多数生产者/消费者工作负载(Lambda、ECS任务)通过AMQP连接,不需要此标签。仅为需要通过HTTP API进行监控或管理的租户添加。
隔离如何强制执行
当租户A的服务连接到代理时:
- 该服务使用其附加的IAM角色凭据承担
TenantARole。 - AWS STS签发一个JWT,其
sub=arn:aws:iam::<account-id>:role/TenantARole。 - 该服务使用JWT作为密码连接到代理。
- 代理将
sub声明与scope别名匹配,并授予configure:tenant-a/*、write:tenant-a/*和read:tenant-a/*。 - 如果服务尝试连接到vhost
tenant-b,代理返回NOT_ALLOWED - access to vhost 'tenant-b' refused for user 'arn:aws:iam::<account-id>:role/TenantARole'。
用于租户隔离的信任策略
每个租户角色使用信任策略来限制哪些主体可以承担它:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account-id>:role/TenantAServiceRole"
},
"Action": "sts:AssumeRole"
}
]
}这确保只有租户A的服务能获得映射到租户A vhost权限的令牌。
客户端认证模式
每个客户端应用程序使用其IAM角色凭据从AWS STS获取短期令牌,然后在连接代理时将该令牌作为密码呈现:
import boto3
import pika
import ssl
class TokenManager:
def __init__(self):
self.sts_client = boto3.client("sts")
def get_token(self, role_arn: str) -> str:
# Assume the tenant's IAM role
assumed = self.sts_client.assume_role(
RoleArn=role_arn,
RoleSessionName="rabbitmq-session"
)
# Create STS client with assumed role credentials
sts = boto3.client(
"sts",
aws_access_key_id=assumed["Credentials"]["AccessKeyId"],
aws_secret_access_key=assumed["Credentials"]["SecretAccessKey"],
aws_session_token=assumed["Credentials"]["SessionToken"],
)
# Get web identity token
response = sts.get_web_identity_token(
Audience=["rabbitmq"],
SigningAlgorithm="ES384",
DurationSeconds=300,
)
return response["WebIdentityToken"]
class RabbitMQClient:
def __init__(self, broker_host: str, vhost: str, role_arn: str):
self.broker_host = broker_host
self.vhost = vhost
self.role_arn = role_arn
self.token_manager = TokenManager()
def connect(self) -> pika.channel.Channel:
token = self.token_manager.get_token(self.role_arn)
credentials = pika.PlainCredentials(
username="", password=token
)
parameters = pika.ConnectionParameters(
host=self.broker_host,
port=5671,
virtual_host=self.vhost,
credentials=credentials,
ssl_options=pika.SSLOptions(ssl.create_default_context()),
)
return pika.BlockingConnection(parameters).channel()令牌管理器会缓存令牌并在到期前刷新,因此您的应用程序不会在每次连接时都请求新令牌。对于Lambda之外的长连接(如Amazon ECS任务或EC2托管的服务),请添加连接恢复逻辑,以优雅地处理令牌过期,并在需要时使用新令牌重新连接。
比较IAM身份验证与其他方法
下表比较了IAM身份验证与Amazon MQ for RabbitMQ可用的其他身份验证方法,以便您选择最适合您安全和运营需求的方法。
| 方面 | IAM(通过STS的OAuth 2.0) | OAuth 2.0(外部IdP) | 用户名/密码 |
| 身份提供商 | IAM / STS | 外部OAuth 2.0 IdP | 代理本地 |
| 凭据类型 | 短期JWT | 短期JWT | 静态密码 |
| 凭据管理 | 通过IAM角色自动管理 | 由外部IdP管理 | 手动创建和轮换 |
| 租户隔离 | 每角色范围别名在代理层限制vhost访问 | 令牌范围 | 手动每用户权限 |
| 审计跟踪 | AWS CloudTrail | IdP特定日志 | 仅代理日志 |
| AWS集成 | 原生(IAM角色、STS、CloudTrail) | 需要外部IdP配置 | 无 |
实施指南
- 在Amazon MQ for RabbitMQ中使用IAM身份验证和授权 – 逐步教程,启用IAM身份验证、配置rabbitmq.conf、获取JWT令牌并通过AMQP连接。
- Amazon MQ for RabbitMQ的IAM身份验证和授权 – IAM身份验证的工作原理及已知限制的概念。
清理
为避免持续费用,请删除您在本次演练中创建的资源:
- 删除测试IAM角色(
TenantARole、TenantBRole)及其关联的信任策略。 - 如果您为测试创建了专用Amazon MQ代理,请从Amazon MQ控制台删除该代理。
- 从代理配置中删除任何测试虚拟主机及其队列。
对于生产部署,请保留您的IAM角色和代理配置,但定期审查您的范围别名,以移除未使用的租户映射。
结论
本文演示了基于IAM的OAuth 2.0身份验证如何用于Amazon MQ for RabbitMQ,以及每租户IAM角色结合代理范围别名如何强制多租户隔离。客户端使用其现有的IAM角色进行身份验证,AWS STS签发短期JWT,代理使用AWS STS JWKS端点验证令牌。范围别名将每个角色ARN映射到特定vhost的权限,确保租户只能访问自己的资源。
结合第1部分中介绍的基于证书的身份验证,以及第2部分中介绍的OAuth 2.0、LDAP、Entra ID和HTTP集成,您现在对Amazon MQ for RabbitMQ可用的身份验证和授权选项有了详细了解。选择适合您身份基础设施的方法,或组合多种方法以实现深度防御安全。
如果您对本文有疑问或反馈,请在评论部分留言。如需故障排除帮助,请访问AWS re:Post社区中的Amazon MQ板块。
有关Amazon MQ安全的更多信息,请参阅以下资源:
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏