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
事情说清了就结束。临时凭证的核心从来不是“怎么生成”,而是“权限最小化”和“生命周期可控”——这两个点一旦松动,安全模型就塌了一半。
