sts assumerole 是最常用且最可控的临时凭证方案,服务端调用后返回 accesskeyid、secretaccesskey 和 sessiontoken 供前端构造签名请求,权限需通过 iam 角色的信任策略和限制性权限策略(如限定 s3 前缀)实现最小化与生命周期可控。

STS AssumeRole 是最常用也最可控的临时凭证方案
客户端直传文件到 S3,又不想暴露长期密钥,核心就是让服务端用 STS 换一组带限制的短期凭证。AWS 官方推荐路径是服务端调用 AssumeRole,返回 AccessKeyId、SecretAccessKey 和 SessionToken 给前端,前端用这三元组构造签名请求。
关键点在于:角色(Role)必须提前在 IAM 中配置好,且信任策略允许你的后端服务(如 EC2 实例角色或 Lambda 执行角色)调用 AssumeRole;权限策略则限定该临时凭证只能写入指定 S3 前缀,比如 "Resource": "arn:aws:s3:::my-bucket/uploads/${aws:username}/*"。
- 别直接在前端硬编码
AssumeRole调用——那等于把后端密钥暴露了 - 临时凭证有效期建议设为 15–60 分钟,太短影响大文件上传中断重试,太长增加泄露风险
- 如果后端跑在 ECS 或 EKS 上,优先用
WebIdentityRole或OIDCProvider方式获取初始凭证,避免手动管理密钥
生成预签名 URL 更轻量,但只适用于服务端可控的上传场景
如果你的 C# 后端能接收文件流再转发给 S3(即不走客户端直传),GeneratePresignedUrl 是更简单的选择。它不返回临时密钥,而是签一个带过期时间、限定操作(如 HttpMethod.PUT)和资源路径的 URL,前端直接 PUT 文件上去即可。
注意这个 URL 本质是“授权链接”,不是“凭证”。它的权限粒度由生成时传入的 PutObjectRequest 决定,比如指定 BucketName、Key 和 Expiration,但无法动态绑定用户身份——所有用这个 URL 上传的人都会写到同一个 Key。
- 要支持多用户上传不同路径?得在生成 URL 前拼好唯一 Key,比如
uploads/{userId}/{guid}.jpg - 预签名 URL 不校验上传内容类型或大小,需在服务端生成前做业务校验(如检查扩展名、预估文件尺寸)
- 不要把预签名 URL 当作长期链接缓存——过期后前端会收到
403 Forbidden,且无法刷新,必须重新请求后端生成
GetFederationToken 适合需要用户名/自定义标签的场景,但权限模型更难收敛
当你要把企业内网账号(比如 AD 用户名)映射成 AWS 身份,并附带标签用于后续审计或策略条件判断时,GetFederationToken 比 AssumeRole 更合适。它返回的凭证里带 Subject 字段,还能通过 Tags 参数传入键值对,比如 new Tag("department", "engineering")。
但它的问题在于:生成的凭证是“联合身份”,不能像 Role 那样天然继承信任策略,所有权限都得靠显式 Attach 的策略文档控制,稍不留神就开太大。而且它不支持 RoleSessionName 的复用机制,每次调用都是新会话。
- 必须手动在策略中用
StringLike或StringEquals限制aws:PrincipalTag/department,否则标签形同虚设 - 如果只是简单上传,别为了“看起来有用户信息”而选它——
AssumeRole+ 自定义RoleSessionName(如upload-{userId})已足够追踪 - 调用频率高时注意
GetFederationToken的 QPS 限制(默认 100 次/秒),突发流量可能触发ThrottlingException
C# SDK v3 的 AssumeRoleResponse 返回字段必须全传给前端
用 AWS SDK for .NET v3 调用 AssumeRoleAsync 后,前端真正需要的是三个字段:Credentials.AccessKeyId、Credentials.SecretAccessKey、Credentials.SessionToken。少传任何一个,前端 SDK(如 aws-sdk-js-v3)初始化 S3Client 就会报 InvalidCredentialsError 或静默失败。
常见错误是只传了前两个,漏掉 SessionToken——这是临时凭证和长期密钥最直观的区别。另外,Expiration 字段也建议一并返回,前端可据此决定是否提前刷新。
- 别把
AssumeRoleResponse整个序列化发过去,冗余字段可能引发前端解析异常 - 别在 C# 里手动拼接签名——交给前端 AWS SDK 处理,它会自动用 SessionToken 签名 v4 请求
- 如果前端用的是
@aws-sdk/client-s3,初始化S3Client时必须传credentials对象,不能只填accessKeyId和secretAccessKey
事情说清了就结束。临时凭证的核心从来不是“怎么生成”,而是“权限最小化”和“生命周期可控”——这两个点一旦松动,安全模型就塌了一半。










