OAuth 2 故障排除
概述
本指南涵盖了使用 OAuth 2.0 和 管理插件 时最常见的错误以及如何诊断它们。
客户端连接故障排除
最大 JWT 令牌长度限制
重现步骤
当客户端连接到配置为使用 JWT 令牌进行身份验证和授权的节点时,可能会遇到消息协议帧长度超出限制的异常。
故障排除
根据编码内容,JWT 令牌的长度可能会有很大差异。RabbitMQ 支持的消息协议对最大帧长度有实际限制。
默认值通常远高于实际可能的 JWT 令牌长度,例如,对于 AMQP 0-9-1 和 RabbitMQ Stream 协议,默认值为 128 kB。但是,最大帧限制可以通过 rabbitmq.conf
和客户端库配置来覆盖。
如果客户端提供了长令牌并且配置了较低的限制,则连接将被拒绝,并在 服务器日志 中显示“帧长度超出”、“帧太大”和类似的错误消息。
例如,在 AMQP 0-9-1 的情况下,它看起来像这样
2025-03-15 05:55:21.689185+00:00 [info] <0.2771.0> accepting AMQP connection <0.2771.0> (10.8.121.164:45024 -> 10.8.121.141:5672)
2025-03-15 05:55:24.745906+00:00 [error] <0.2771.0> closing AMQP connection <0.2771.0> (10.8.121.164:45024 -> 10.8.121.141:5672):
2025-03-15 05:55:24.745906+00:00 [error] <0.2771.0> {handshake_error,starting,0,
2025-03-15 05:55:24.745906+00:00 [error] <0.2771.0> {amqp_error,frame_error,
2025-03-15 05:55:24.745906+00:00 [error] <0.2771.0> "type 1, all octets = <<>>: {frame_too_large,6307,4088}",
2025-03-15 05:55:24.745906+00:00 [error] <0.2771.0> none}}
有两种可用的解决方案
- 增加
rabbitmq.conf
中的initial_frame_max
值,或advanced.config
中的rabbit.initial_frame_max
- 减小令牌内容大小,例如,删除 RabbitMQ 未使用的某些范围或优化(简化)它们
增加初始帧大小限制
以下 rabbitmq.conf
示例将初始帧大小限制增加到 8192 字节(从默认的 4096 字节)
initial_frame_max = 8192
使用 advanced.config
的相同示例
[
{rabbit, [
{initial_frame_max, 8192}
]}
].
减小 JWT 令牌负载大小
通常可以通过删除 RabbitMQ 未使用的某些范围来减小 JWT 令牌大小。或者,可以生成具有更窄范围集的新 JWT 令牌,从而减小大小。
管理 UI 中的 OAuth 2 故障排除
OpenId Discovery 端点无法访问
重现步骤
在浏览器中打开管理 UI 的根 URL。您看到的不是“点击此处登录”按钮,而是以下错误消息
OAuth resource [rabbitmq] not available. OpenId Discovery endpoint https://<the_issuer_url>/.well-known/openid-configuration not reachable
故障排除
这些是导致此问题的最常见原因
识别根本原因的最快方法是打开浏览器的 JavaScript 控制台并搜索 net::ERR_
。最可能的错误是
net::ERR_CONNECTION_REFUSED
:端点已关闭或无法访问net::ERR_CERT_AUTHORITY_INVALID
:端点的 TLS 证书不受浏览器信任。要信任此证书,请单击错误消息中的 URL 并按照提示操作
如果没有错误匹配 net::ERR
,请搜索 CORS
。如果出现类似于以下内容的错误
Access to fetch at 'https://<the_issuer_url>>/.well-known/openid-configuration' from origin
'<rabbitmq_url_to_management_ui>' has been blocked by CORS policy
那么浏览器正在阻止端点返回的响应,因此它没有被传递到管理 UI。这是由于 CORS 策略。请身份提供商的管理员将管理 UI 的 URL 添加到允许的 来源 列表中。
OpenId Discovery 端点不兼容
重现步骤
在浏览器中打开管理 UI 的根 URL。您看到的不是“点击此处登录”按钮,而是以下错误消息
OAuth resource [rabbitmq] not available. OpenId Discovery endpoint https://<the_issuer_url>/.well-known/openid-configuration not compliant
故障排除
当端点未返回与 OpenId Connect Discovery Configuration 匹配的 JSON 负载时,会导致此问题。这些是可能的原因
- 端点返回的负载不兼容,因为它为空或缺少一些关键信息。要识别根本原因,请打开浏览器的 JavaScript 控制台并搜索以下可能的错误消息之一
Payload does not contain openid configuration
当负载为空或不是 JSON 负载时,会发生此错误。Missing authorization_endpoint
当缺少 JSON 属性authorization_endpoint
时,会发生此错误。Missing token_endpoint
当缺少 JSON 属性token_endpoint
时,会发生此错误。Missing jwks_uri
当缺少 JSON 属性jwks_uri
时,会发生此错误。
- URL 错误。从您的身份提供商管理员处检索 OpenId Connect Discovery 端点的正确 URL。
未授权
重现步骤
在浏览器中打开管理 UI 的根 URL。单击“点击此处登录”按钮并输入身份提供商请求的凭据。
您将被重定向回管理 UI,并显示以下错误
Not authorized
故障排除
当令牌没有足够的范围或权限来访问管理 UI 时,会发生此问题。您至少需要以下范围之一或等效范围
rabbitmq.tag:administrator
.rabbitmq.tag:management
.rabbitmq.tag:monitoring
.rabbitmq.tag:policymaker
.
按照以下步骤找出令牌中携带的范围或权限
- 打开浏览器的开发者工具(例如,在 Chrome 或 Firefox 中,右键单击页面并单击“检查”菜单选项)
- 转到“应用程序”选项卡
- 在左侧面板中选择“存储” > “本地存储”选项
- 单击与管理 UI 的 URL 匹配的树选项
- 在右侧面板中选择键
rabbitmq.credentials
- 复制其值
- 导航到 https://jwt.node.org.cn
- 将值粘贴到“Encoded”文本字段中
- 查看负载的“Decoded”文本字段
- 在令牌的负载中搜索令牌属性
scope
,或者搜索在auth_oauth2.additional_scopes_key
中配置的值(如果有) - 找到适当的令牌范围属性后,在属性值中查找上面列出的任何范围。如果使用了 auth_oauth2.scope_prefix,则必须考虑在内:范围的命名将类似于
myprefix_tag:administrator
。如果使用了 范围别名,请查找映射到上面列出的范围之一的范围别名
由于证书错误导致 OpenId Discovery 端点无法访问
此问题不一定特定于管理 UI,当应用程序通过其中一种消息协议进行身份验证时也可能发生。当 RabbitMQ 必须通过 auth_oauth2.issuer
中配置的 URL 下载 OpenId Connect 配置,并且颁发者使用的证书使用通配符证书时,就会发生这种情况。这意味着证书的 CN 属性与颁发者的域名不完全匹配。这在 SaaS 部署中非常常见。
重现步骤
- 在浏览器中打开管理 UI 的根 URL。
- 单击“点击此处登录”。
- 输入您的凭据。
- 您将被重定向回 RabbitMQ,但出现“未授权”错误。
故障排除
- 访问 RabbitMQ 日志
- 查找
{bad_cert,hostname_check_failed}
- 如果您找到一个条目,则表示 RabbitMQ 尝试联系
auth_oauth2.issuer
中找到的 URL,并且颁发者提供了通配符证书 - 要解决此问题,请将以下行添加到
rabbitmq.conf
:auth_oauth2.https.hostname_verification = wildcard
,或者如果使用多个身份提供商,则添加auth_oauth2.oauth_providers.<my_oauth_provider_name>.https.hostname_verification = wildcard