身份认证:玩转 AccessKey、SecretKey、临时凭证与 STS
身份认证这一块,说白了就是回答三个问题:你是谁?你有什么权限?你的凭证还能用多久? 对象存储不像你电脑上的本地文件夹,谁都能往里拽东西。每次请求都得带上一套身份证明,服务器才会给你开门。
我接触过的不少新手,刚开始都在这上面吃过亏。直接把密钥明文写在代码里,结果代码一泄漏,整个存储桶就「裸奔」了。嗯,咱们今天就把这块彻底讲清楚。
4.1 长期凭证:AccessKey 与 SecretKey
这是最基础的身份凭证。你可以理解为对象存储世界的「用户名和密码」。
- AccessKey(简称 AK):身份标识,相当于你的账号 ID。它是公开的,会随请求一起发送。
- SecretKey(简称 SK):签名密钥,相当于你的登录密码。它必须严格保密,绝不随请求明文传输。
核心流程是:你用 SK 对请求参数(路径、时间戳、HTTP 方法等)进行签名计算,生成一串独一无二的签名。服务端收到请求后,用你的 AK 查到对应的 SK,用同样的规则重新算一遍签名。只有两个签名一致,请求才被放行。
为什么要这样设计?原因很简单。就算请求在传输过程中被截获,攻击者拿不到你的 SK,也无法伪造合法请求。我在项目初期就踩过这个坑,把 SK 当作普通参数拼接在 URL 里,结果被安全审计直接打回。
4.2 临时凭证:临时密钥与 STS
长期虽然稳定,但也有个大问题:一但泄漏,除非手动吊销,否则永远有效。有没有一种方式可以给它设置个有效期?这就是临时凭证登场的原因。
4.2.1 什么是 STS
STS 全称是 Security Service,中文叫安全凭证服务。它的作用很简单:帮你生成有时效限制的临时凭证。
用 STS 获取到的临时凭证,包含三样东西:
- 临时 AccessKey:和长期 AK 结构类似,但有时效。
- 临时 SecretKey:对应的签名密钥,同样有时效。
- Security :一个会话令牌,证明这是由 STS 签发的一次性凭证。
你拿着这三样东西,就可以像长期凭证一样去调用 SDK。服务端看到请求中带有 Security ,就知道这是一次临时授权。期限到了,凭证自动失效,无需人工干预。
我记得有一次,公司的前端需要直接从浏览器上传文件到对象存储。直接把长期 AK/SK 写在 JS 里肯定不行。那时候我就用 STS 接口,让后端每 30 分钟签一次临时凭证给前端。就算有用户扒了我的 JS 代码,也只能拿到一张半小时后过期的票。
4.3 长期凭证 vs 临时凭证:怎么选
你可以对比一下:
| 特性 | 长期凭证 (AK/SK) | 临时凭证 (STS) |
|---|---|---|
| 有效期 | 永久(除非手动撤销) | 可自定义(通常 15 分钟~36 小时) |
| 泄漏风险 | 高,泄漏后影响持久 | 低,过期即失效 |
| 管理成本 | 低,一次申请长期使用 | 稍高,需定期调用 STS 接口获取 |
| 常见场景 | 服务端后台任务、运维脚本 | 移动端 App、Web 前端、第三方临时授权 |
你想想看,临时凭证天然适合那些「你不完全信任」的运行环境。比如用户的浏览器、你的合作伙伴的服务器。长期凭证则适合你完全掌控的内部服务。
4.4 核心逻辑示意图
下面这张图把整个认证体系和临时凭证申请流转画清楚了。你一看就应该明白:
4.5 最佳实践:到底怎么选
给你几条我总结出来的铁律:
- 服务端本身的自动化任务:用长期 AK/SK。比如每晚的日志转存、数据备份。这类环境安全可控,长期凭证的便利性远大于风险。
- 有用户交互的客户端:一定用 STS 临时凭证。不管是浏览器、移动 App 还是桌面软件,运行环境都不在你的掌控之下。临时凭证过期即失效的特性是关键。
- 临时授权给第三方合作伙伴:STS 也是不二之选。你可以限制临时凭证只能操作某个特定「前缀」目录,甚至只能上传不能下载。权限粒度可以做到很细。
- 安全兜底:定期轮换长期密钥。 即使你应该尽量少用长期凭证,但如果你不得不使用,建议设置一个定时任务,每 90 天自动生成新的 AK/SK 并废弃旧密钥。我所在的项目组现在就是用脚本自动做这件事,省去了很多人力审计的麻烦。