华为云 OBS 返回 403 AccessDenied:从错误码到权限策略的排查清单

举报
yd_294423728 发表于 2026/10/31 11:34:36 2026/10/31
【摘要】 OBS 返回 403 不一定是缺 IAM 权限。本文先教你读懂错误响应里的 Code、Message(user/action/resource/policy_type)和 RequestId,再按身份与AK/SK、跨账号、Resource/Action、显式Deny、securitytoken、签名与时钟、防盗链、BPA、KMS等层次逐项排查,并附对照表。

引言

用 SDK、obsutil、OBS Browser+ 或者浏览器访问 OBS 时,最让人头疼的往往是一个 403 Forbidden。很多人一看到 403 就去加 IAM 权限,结果权限越加越大,问题还在。实际上 OBS 里返回 403 的错误码不止 AccessDenied 一个,签名、时钟、密钥、欠费都可能落在 403 上;即使确实是 AccessDenied,也可能来自 IAM 策略、桶策略、ACL、防盗链、阻止公共访问(BPA)、VPCEP 策略等不同层面。

这篇按「先看响应 → 再分层排查」的顺序整理成一份清单,所有结论都对照了华为云 OBS 官方文档(链接见文末)。

第一步:先看错误码和请求 ID,别急着改权限

OBS 报错时的响应由状态码、响应头和 XML 响应体组成,其中最关键的几个字段是:

HTTP/1.1 403 Forbidden
x-obs-request-id: <RequestId>
<Error>
  <Code>AccessDenied</Code>
  <Message>...</Message>
  <RequestId>...</RequestId>
  <HostId>...</HostId>
  <BucketName>example-bucket</BucketName>
  <Key>path/to/object</Key>
</Error>
  • Code:通用错误码,决定排查方向。
  • Message:详细原因。新版鉴权的 AccessDenied 会直接写明是谁(user)、做什么操作(action)、对哪个资源(resource)、被哪类策略(policy_type)拒绝。
  • RequestId / x-obs-request-id:请求唯一标识,提工单时连同桶名、对象名一起提供。

我习惯先用 curl -v 或 SDK 的调试日志把完整响应拿下来,再对照下表判断方向:

状态码 / 错误码 含义(官方) 方向
403 AccessDenied 没有权限执行操作 权限策略、防盗链、BPA、WORM 等
403 SignatureDoesNotMatch 服务端算出的签名与请求不一致 SK、StringToSign、Endpoint
403 InvalidAccessKeyId 系统中不存在该 AK AK 填错、已删除
403 RequestTimeTooSkewed 客户端与服务端时间差超过 15 分钟 系统时钟
403 AccessForbidden 桶未配置 CORS 或规则不匹配 CORS
403 InArrearOrInsufficientBalance 欠费或余额不足 账户
403 InvalidObjectState 归档/深度归档对象需先恢复 存储类别

AccessDenied 的 Message 如果是 ... because no <policy_type> policy allows ...,说明是没有被明确授权;如果是 ... with an explicit deny in ... policy,说明是被显式拒绝。policy_type 取值含义:identity-based 是 IAM 策略,resource-based 是桶策略或 ACL(显式拒绝场景只会是桶策略),session 是 VPCEP 策略,service control 是组织的服务控制策略(SCP)。看懂这一行,往往就能直接定位到该改哪里。

编号排查步骤

1. 确认用的是哪个身份、哪对 AK/SK

官方 FAQ 把「使用了错误的账号或 AK/SK」列为高频原因之一:权限给了用户 A,实际请求却用的是用户 B 的 AK/SK。常见的情况是环境变量、配置文件、SDK 代码里各有一套密钥。可以把 Message 里的 user、SignatureDoesNotMatch 响应里的 AccessKeyId 和自己以为在用的身份对比一下。

# 只看当前进程拿到的是哪个 AK(只打印前几位,不要打印 SK)
echo "${OBS_AK:0:4}****"

2. 同账号还是跨账号

  • 同账号:IAM 策略(推荐)或桶策略任选其一授权即可。
  • 跨账号(账号 A 访问账号 B 的桶):需要 A 的管理员用 IAM 给自己的用户授权,同时 B 的桶拥有者用桶策略或 ACL 给 A 的用户授权,只配一边会 403。另外官方说明暂不支持用控制台跨账号访问桶,需要用 OBS Browser+、API、SDK 或 obsutil。

3. 核对 Resource 和 Action

官方总结的常见错误:

  • Resource 只授权了桶 A,却访问桶 B;只授了桶级权限,却操作桶内对象;只授了对象权限,却列举桶。
  • Action 配错或遗漏,比如要上传(PutObject)却只给了下载(GetObject)。
  • 策略里写了 Condition(如源 IP),要确认请求满足条件。

一个只授予上传权限的桶策略示例(占位符请替换):

{
  "Statement": [
    {
      "Sid": "allow_put",
      "Action": ["PutObject"],
      "Effect": "Allow",
      "Resource": "example-bucket/*",
      "Principal": { "ID": ["domain/<domain-id>:user/<user-id>"] }
    }
  ]
}

4. 控制台 / OBS Browser+ 访问还要额外的列举权限

给用户配置 OBS OperateAccess 等系统权限或桶读写权限后,用 API/SDK 正常,但在控制台、OBS Browser+ 里提示「拒绝访问」——这是因为界面加载桶列表、对象列表时会调用 ListAllMyBuckets、ListBucket 等接口。桶开启多版本时,还需要 obs:bucket:ListBucketVersions。

5. 查找显式 Deny

OBS 权限遵循 Deny 优先:IAM 策略、桶策略、VPCEP 策略、SCP 中任一处显式 Deny,都会覆盖其他地方的 Allow。逐项检查这四类策略里是否有 Deny 命中当前 action。

6. 临时 AK/SK 是否带了 securitytoken

用 IAM 获取的临时访问密钥时,临时 AK/SK 和 securitytoken 必须一起用:Header 签名需加 x-obs-security-token 头域(并参与签名),URL 签名需带 x-obs-security-token 参数。临时密钥有效期为 15 分钟到 24 小时;如果获取时传了 policy,有效权限是 IAM 用户原有权限与临时策略的交集,临时策略里没写的权限默认拒绝。

PUT /object.txt HTTP/1.1
Host: example-bucket.obs.<region-id>.myhuaweicloud.com
x-obs-date: <GMT 时间>
x-obs-security-token: <security-token>
Authorization: OBS <临时AK>:<Signature>

7. 签名与时钟

  • RequestTimeTooSkewed:客户端与服务端时间差大于 15 分钟会被拒绝。先 date -u 看 UTC 时间,不准就用 NTP / chrony 等时间同步服务校正。
  • SignatureDoesNotMatch:响应里会返回服务端的 StringToSign,和客户端的逐行对比。常见原因有:SK 不匹配;漏了 x-obs-* 头域或 ?acl 这类 query 参数;URL 签名应使用 Expires 而不是 Date;SDK 的 Endpoint 误填成了桶域名(应为 obs.<region-id>.myhuaweicloud.com,前面不加桶名)。官方推荐尽量用 SDK,避免手工算签。
date -u   # 与真实 UTC 时间相差不应接近 15 分钟

8. 防盗链(Referer)

防盗链的检查发生在读写权限判断之前。规则要点:白名单非空时,只有在白名单且不在黑名单的 Referer 才能访问;黑白名单有交集时交集部分被禁止;如果下载时 Referer 带 http/https,规则里也要带。浏览器的 Referrer-Policy: no-referrer、<video> 播放等会产生空 Referer,配白名单时需要考虑打开「允许空 Referer」。桶日志中 Referer 字段为 - 表示空 Referer,可以据此核对。

9. 阻止公共访问(BPA)

桶开启 BPA 后:BlockPublicAcls 开启时设置含公开语义的对象 ACL 会被拒绝;RestrictPublicBuckets 开启且桶策略里有公开策略时,其他操作也可能被拒。可在「权限控制 > 阻止公共访问」查看开关。

10. 加密对象的 KMS 权限

SSE-KMS 加密的对象:匿名用户不能访问,即使对象是公共读;相关 GET/PUT 请求必须使用 HTTPS;下载时除了对象下载权限,还需要 IAM 授予 kms:cmk:get、kms:cmk:list、kms:cmk:create、kms:dek:create、kms:dek:encrypt、kms:dek:decrypt。使用自定义密钥时,桶和密钥必须在同一区域;跨账号场景应使用自定义密钥。需要给匿名用户看加密对象,可以用对象分享生成的临时 URL。

11. 其他 403:WORM、欠费、归档、缓存

  • 试图修改或删除受 WORM 保护的对象,会返回 AccessDenied,只能等保护期过。
  • 欠费、余额不足、账号受限或冻结也会 403。
  • 归档 / 深度归档对象要先恢复才能下载。
  • 对象不存在也可能是 403:有 GetObject 但没有 ListBucket 权限时,下载不存在的对象返回 403 而不是 404。
  • IAM 策略修改后一般要 10~15 分钟才生效,改完立刻测试失败不代表配置错了。

12. 区域 / Endpoint 不对通常不是 403

请求发到了错误区域的地址,官方错误码是 301 PermanentRedirect,按返回的地址重发即可;而 SDK 把 Endpoint 写成桶域名,表现为 SignatureDoesNotMatch。所以如果看到的是 301 或签名错误,优先核对 Endpoint 与桶所在区域。

现象-可能原因-怎么确认

现象 可能原因 怎么确认
Message 含 no ... policy allows 未授权或 Resource/Action 不覆盖 按 user/action/resource/policy_type 查对应策略
Message 含 explicit deny IAM/桶策略/VPCEP/SCP 显式 Deny 在 policy_type 指向的策略里找 Deny
API 正常,控制台/Browser+ 拒绝 缺 ListAllMyBuckets / ListBucket 检查 IAM 自定义策略
跨账号只有一方配了权限 缺 IAM 或桶策略/ACL 其中一侧 两个账号分别核对
临时密钥 403 没带 securitytoken、已过期、临时策略未授权 检查请求头/URL 参数与有效期
SignatureDoesNotMatch SK 错、StringToSign 不一致、Endpoint 含桶名 对比响应中的 StringToSign、AccessKeyId
RequestTimeTooSkewed 时钟偏差超过 15 分钟 date -u
网页嵌入 403,直接访问正常(或反之) 防盗链规则、空 Referer 看防盗链配置与桶日志 Referer 字段
设置公共读 ACL / 策略被拒 BPA 开关 权限控制 > 阻止公共访问
加密对象下载 403,普通对象正常 缺 KMS 权限、HTTP 访问、匿名访问 核对 IAM 中 KMS 授权与协议
下载不存在的对象返回 403 无 ListBucket 权限 授予 ListBucket 后应返回 404
刚改完权限仍 403 IAM 缓存 等 10~15 分钟重试

小结

OBS 的 403 排查,我一般按三层走:先看 Code(区分权限、签名、时钟、账户问题);再读 Message(user / action / resource / policy_type 往往直接指出该改哪个策略);最后按层核对身份与 AK/SK、同账号还是跨账号、Resource/Action、显式 Deny、securitytoken、防盗链、BPA、KMS。改完 IAM 记得等 10~15 分钟。仍解决不了时,把 RequestId、桶名、对象名整理好提工单,定位会快很多。

参考

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。