题干与适用场景
这道系统设计题考察临时凭证的生命周期与权限边界。重点不是把对象存储的签名 API 包一层,而是让链接只拥有必要能力,在泄露、撤销、密钥轮换和跨区域访问时仍可控可追踪。
面试官考察什么
- 能否把签名 URL 绑定到租户、对象、HTTP 方法、版本、范围和过期时间。
- 能否区分签名验证、实时授权、撤销和对象存储实际权限。
- 能否设计密钥轮换、短期缓存、CDN 分发、限流和审计数据流。
- 能否解释 URL 泄露、重放、时钟偏差、区域故障和撤销延迟的取舍。
回答前需要澄清的问题
先确认下载还是上传、单对象还是批量、是否支持 Range 和分片、链接最长有效期、撤销是否要求秒级生效,以及访问是否经过 CDN。还要确认租户隔离、审计保留期、密钥管理服务、跨区域容灾和对象版本语义。
30 秒回答框架
我会让授权服务先验证调用者,再签发绑定租户、对象版本、操作、条件和短过期时间的 URL。签名使用密钥版本和规范化请求,存储端或边缘验证签名;高风险撤销通过短 TTL、deny-list 或版本吊销标记实现。URL 只授予最小权限,访问事件进入不可变审计流,并通过限流、重放检测和密钥轮换控制风险。
分步骤深入解答
1. 定义凭证模型与权限
令牌至少包含租户、对象键或不可猜的对象 id、版本、允许的方法、字节范围、内容类型约束、签发者、过期时间和密钥版本。上传 URL 还应限制大小、校验和和目标前缀。服务端先做实时对象授权,再把最终允许的条件写入签名,避免客户端修改参数扩大权限。
2. 选择签名与验证路径
可使用云存储兼容的 HMAC 或非对称签名,签名覆盖 HTTP 方法、路径、查询参数、关键头和过期时间,并对空白、编码和参数排序做规范化。验证方检查时间窗口、密钥版本、签名和条件;关键操作仍需服务端实时检查,而不是把所有授权都缓存到 URL。
3. 设计撤销、轮换与重放防护
短过期时间限制泄露影响;撤销高价值链接时,可在 Redis 或边缘规则中记录令牌 id、对象版本或租户 deny-list。密钥轮换保留旧版本到最长 URL 生命周期结束,再删除旧密钥。一次性上传可要求 nonce、对象状态和完成标记,重复下载则按业务允许多次还是绑定设备决定。
4. 扩展存储、CDN 与故障处理
签发服务保持无状态,元数据和撤销记录由高可用存储承载;对象内容直接走存储或 CDN,避免应用服务器中转大文件。CDN 缓存必须把签名和权限边界纳入策略,不能缓存一个租户的私密响应给另一个租户。密钥管理或撤销存储暂时不可用时,对新签发和高风险访问采取 fail-closed,已签发低风险链接按明确 TTL 处理。
5. 观测、限流和安全验证
审计事件记录签发者、租户、对象、方法、结果、区域、客户端指纹摘要和撤销原因,不记录完整 URL 查询串。按租户、用户、对象和 IP 限制签发频率、总字节和并发,检测同一令牌异常重放。测试参数篡改、过期、时钟偏差、密钥轮换、撤销延迟、跨租户访问、CDN 命中和区域故障。
高质量示范回答
授权服务验证调用者后,签发绑定租户、对象不可变版本、方法、必要条件和短过期时间的 URL,签名覆盖规范化路径、查询参数和关键头。对象存储或 CDN 验证签名,应用不转发大文件;高风险链接用短 TTL、deny-list 或版本吊销支持撤销。旧密钥保留到最长链接过期后删除。审计流记录签发与访问结果但不记录完整 URL,限流覆盖租户和对象。测试参数篡改、重放、时钟偏差、跨租户、轮换、撤销和 CDN 缓存隔离。
常见错误
- 只签名对象路径,没有绑定租户、方法、版本或上传条件。
- 把永久 URL 当成撤销凭证,泄露后无法快速止损。
- 轮换密钥时立刻删除旧密钥,导致合法链接全部失效。
- 让 CDN 只按路径缓存私密内容,忽略签名和租户边界。
- 把完整签名 URL 写入日志、分析系统或错误消息。
- 只测签名正确性,不测参数篡改、重放、时钟偏差和撤销延迟。
追问及应对
为什么不把所有授权都放进 JWT?
签名 URL 可以把条件绑定到资源请求并由存储验证,应用不必代理大文件;但它仍不是实时撤销系统。高风险权限需要短 TTL、版本吊销或实时检查,不能只依赖自包含令牌。
如何实现秒级撤销?
让边缘或验证层检查高优先级 deny-list、对象版本吊销标记或租户状态,并设置极短缓存 TTL。代价是每次访问增加存储读取和一致性压力,需要按风险分层。
上传 URL 如何避免覆盖别人的对象?
签名绑定不可变对象键或一次性上传 id、If-None-Match、大小和校验和;完成时服务端再次确认租户和对象状态,拒绝路径替换和重复完成。
CDN 应该缓存签名 URL 吗?
可以缓存内容,但缓存键、响应头和 TTL 必须保证不同权限不会共享私密响应。对高风险或短时资源可绕过共享缓存,牺牲命中率换取隔离和撤销可控性。