身份认证:玩转 AccessKey、SecretKey、临时凭证与 STS

身份认证这一块,说白了就是回答三个问题:你是谁?你有什么权限?你的凭证还能用多久? 对象存储不像你电脑上的本地文件夹,谁都能往里拽东西。每次请求都得带上一套身份证明,服务器才会给你开门。

我接触过的不少新手,刚开始都在这上面吃过亏。直接把密钥明文写在代码里,结果代码一泄漏,整个存储桶就「裸奔」了。嗯,咱们今天就把这块彻底讲清楚。

4.1 长期凭证:AccessKey 与 SecretKey

这是最基础的身份凭证。你可以理解为对象存储世界的「用户名和密码」。

  • AccessKey(简称 AK):身份标识,相当于你的账号 ID。它是公开的,会随请求一起发送。
  • SecretKey(简称 SK):签名密钥,相当于你的登录密码。它必须严格保密,绝不随请求明文传输。

核心流程是:你用 SK 对请求参数(路径、时间戳、HTTP 方法等)进行签名计算,生成一串独一无二的签名。服务端收到请求后,用你的 AK 查到对应的 SK,用同样的规则重新算一遍签名。只有两个签名一致,请求才被放行。

为什么要这样设计?原因很简单。就算请求在传输过程中被截获,攻击者拿不到你的 SK,也无法伪造合法请求。我在项目初期就踩过这个坑,把 SK 当作普通参数拼接在 URL 里,结果被安全审计直接打回。

核心原则:AK 可以公开,SK 必须保密。永远不要在前端代码、日志文件、版本控制系统中暴露 SK。
我个人的习惯:长期凭证只在服务端或内部工具中使用。如果你只是想本地调试,强烈建议创建独立的子账号 AK/SK,并限定其权限范围。这样即便泄漏,也能把伤害降到最低。

4.2 临时凭证:临时密钥与 STS

长期虽然稳定,但也有个大问题:一但泄漏,除非手动吊销,否则永远有效。有没有一种方式可以给它设置个有效期?这就是临时凭证登场的原因。

4.2.1 什么是 STS

STS 全称是 Security Service,中文叫安全凭证服务。它的作用很简单:帮你生成有时效限制的临时凭证。

用 STS 获取到的临时凭证,包含三样东西:

  • 临时 AccessKey:和长期 AK 结构类似,但有时效。
  • 临时 SecretKey:对应的签名密钥,同样有时效。
  • Security :一个会话令牌,证明这是由 STS 签发的一次性凭证。

你拿着这三样东西,就可以像长期凭证一样去调用 SDK。服务端看到请求中带有 Security ,就知道这是一次临时授权。期限到了,凭证自动失效,无需人工干预。

我记得有一次,公司的前端需要直接从浏览器上传文件到对象存储。直接把长期 AK/SK 写在 JS 里肯定不行。那时候我就用 STS 接口,让后端每 30 分钟签一次临时凭证给前端。就算有用户扒了我的 JS 代码,也只能拿到一张半小时后过期的票。

曾经踩过的坑:临时凭证过期后,上传中的大文件会直接失败。如果你要分片上传,必须确保整个分片请求在凭证有效期内完成,或者使用支持自动刷新的 SDK 版本。我一个同事没注意这细节,上线后大文件上传成功率只有 60%。

4.3 长期凭证 vs 临时凭证:怎么选

你可以对比一下:

特性 长期凭证 (AK/SK) 临时凭证 (STS)
有效期 永久(除非手动撤销) 可自定义(通常 15 分钟~36 小时)
泄漏风险 高,泄漏后影响持久 低,过期即失效
管理成本 低,一次申请长期使用 稍高,需定期调用 STS 接口获取
常见场景 服务端后台任务、运维脚本 移动端 App、Web 前端、第三方临时授权

你想想看,临时凭证天然适合那些「你不完全信任」的运行环境。比如用户的浏览器、你的合作伙伴的服务器。长期凭证则适合你完全掌控的内部服务。

4.4 核心逻辑示意图

下面这张图把整个认证体系和临时凭证申请流转画清楚了。你一看就应该明白:

对象存储身份认证核心逻辑图 长期凭证(AK/SK) 用户创建 AK/SK 对 SDK 使用 SK 签名请求 服务端校验签名 临时凭证(STS 流程) 1. 应用服务端调用 STS 2. 返回临时凭证 (临时AK/SK + ) 3. 前端/客户端获取凭证 4. SDK 用临时凭证请求 5. 服务端校验有效期与权限 最佳实践 服务端内部用长期凭证,前端/移动端/第三方用临时凭证,绝不将 SK 泄漏到不可控环境

4.5 最佳实践:到底怎么选

给你几条我总结出来的铁律:

  1. 服务端本身的自动化任务:用长期 AK/SK。比如每晚的日志转存、数据备份。这类环境安全可控,长期凭证的便利性远大于风险。
  2. 有用户交互的客户端:一定用 STS 临时凭证。不管是浏览器、移动 App 还是桌面软件,运行环境都不在你的掌控之下。临时凭证过期即失效的特性是关键。
  3. 临时授权给第三方合作伙伴:STS 也是不二之选。你可以限制临时凭证只能操作某个特定「前缀」目录,甚至只能上传不能下载。权限粒度可以做到很细。
  4. 安全兜底:定期轮换长期密钥。 即使你应该尽量少用长期凭证,但如果你不得不使用,建议设置一个定时任务,每 90 天自动生成新的 AK/SK 并废弃旧密钥。我所在的项目组现在就是用脚本自动做这件事,省去了很多人力审计的麻烦。
我的一个小建议:除了安全,还要考虑性能。每次临时凭证都需要一次额外的 HTTP 请求去 STS 服务换取。对于高频小文件操作,这个延迟可能不可忽略。这时候可以考虑在服务端缓存临时凭证,在过期前提前续期,而不是每次上传都去申请一次。