调用SDK或者API,如果出现“403 AccessDenied”或“The OwnerId that your Access Key Id associated to is forbidden for this operation”错误时, 一般是因为跨域访问队列,或者是使用了错误的OwnerId,或者是没有正确配置主账号RAM信息(使用子账号访问)。
问题描述
调用轻量消息队列(原 MNS)的SDK或者API时,出现如下错误。
[Error Code]:403 AccessDenied [Message]:The OwnerId that your Access Key Id associated to is forbidden for this operation.
问题原因
引发该报错的可能性如下。
-
跨地域访问轻量消息队列(原 MNS)队列。
-
使用私网队列地址时,生产端、消费端必须部署在相应地域的ECS上,否则会报上述错误。
-
使用公网队列地址时,生产端、消费端可以部署在本地,也可以部署在任意地域且开通公网访问的ECS上。
-
-
OwnerId配置错误。OwnerId指阿里云账号的账号ID,您可以登录轻量消息队列(原 MNS)控制台,将鼠标悬浮在右侧头像处,在展开的浮窗中获取账号ID。
-
错误的RAM用户或者RAM用户权限配置异常。
-
调用HTTP API时,使用的URL地址与标志头不对应。详情请参考更多信息。
-
使用了非阿里云官方的SDK。
解决方案
请参考如下步骤进行排查。
-
登录轻量消息队列(原 MNS)控制台,切换到MNS实例所在的地域,单击队列列表,确认存在您创建的轻量消息队列(原 MNS)实例。在操作列单击详情,在详情页的接入点区域获取Endpoint信息。
说明获取的Endpoint地址中,以数字开头的信息即为OwnerId。
接入点区域显示两种 Endpoint:公网访问地址格式为
http(s)://<OwnerId>.mns.<region>.aliyuncs.com,内网访问地址格式为http(s)://<OwnerId>.mns.<region>-internal.aliyuncs.com。 -
检查生产端和消费端使用的Endpoint地址和OwnerId是否正确。
-
检查生产端和消费端是否符合如下原则。如果不符合,需要参考如下原则进行调整。
-
使用私网队列地址时,生产端、消费端必须部署在相应地域的ECS上。
-
使用公网队列地址时,生产端、消费端可以部署在本地,也可以部署在任意地域且开通公网访问的ECS上。
-
-
如果使用RAM用户访问轻量消息队列(原 MNS)实例,请检查主账号的RAM配置是否正确。例如,主账号RAM配置中授权的资源如下,RAM用户实际访问的队列是
/queues/busi-msn/messages,那么也会由于不匹配,导致报错。关于如何配置RAM用户,请参见创建RAM用户。"Resource": [ "acs:mns:*:*:/queues", "acs:mns:*:*:/queues/busi-test", "acs:mns:*:*:/queues/busi-test/*" -
如果排查完以上几点后,该报错仍然存在,可能是因为您使用了非官方的SDK或者调用HTTP API时,使用的URL地址与标志头不对应。详情请参考更多信息。
更多信息
轻量消息队列(原 MNS)在正式商用前,名为MQS。正式商用前后,获取Endpoint中显示的信息是不同的。
-
正式商用前,Endpoint地址为
http://y9g.mqs-cn-beijing.aliyuncs.com/。 -
正式商用后,Endpoint地址为
http://44404.mns.cn-beijing.aliyuncs.com/。
上述Endpoint地址仅为示例,现场以实际情况为准。后文中旧Endpoint地址指http://y9g.mqs-cn-beijing.aliyuncs.com/;新Endpoint地址指http://44404.mns.cn-beijing.aliyuncs.com/。
轻量消息队列(原 MNS)正式商用后,在兼容旧协议规则的同时,启用了新协议规则。http header x-mns-version就是服务端用来识别新旧协议的标志头。
-
如果用户发送的请求包含
x-mns-version: 2015-06-06,服务端将使用新协议规则解析。 -
如果用户发送的请求包含
x-mqs-version: xxxx-xx-xx,服务端将使用旧协议规则解析
因此,您需要参考如下规范来使用轻量消息队列(原 MNS)。
-
调用HTTP API时,请求中的URL地址必须和标志头对应。如果URL使用新地址,标志头却用
x-mqs-version:xxxx-xx-xx,那么还是会报错。 -
使用SDK时,如果使用非官方SDK,非官方SDK可能没有新旧Endpoint地址识别的功能,当用户使用新Endpoint地址时,可能会出现问题。建议使用阿里云官方SDK,一方面能够得到有保证的支持,另一方面官方SDK提供了BatchSendMessage、BatchReceiveMessage等批量操作,可以带来更高的消息处理效率,而这些功能是没有包含在非官方SDK包里的。如果不想更改已有代码,坚持使用非官方SDK(不推荐),则可以联系阿里云技术支持获取旧Endpoint地址。