调用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地址和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地址。