安全生成sts临时凭证需调用assumerole接口,预设ram角色并最小化授权,设置900秒过期;后端生成post policy须json序列化、utf-8编码,签名密钥为secretaccesskey+"&"+securitytoken;回调必须验证且公网可达。

STS临时凭证怎么生成才安全
后端不能硬编码AccessKey,也不能把长期密钥下发给前端。必须用阿里云STS服务动态签发临时Token,且权限要最小化。
-
AssumeRole接口是唯一合规方式,需在RAM中预设角色并授权AliyunOSSReadOnlyAccess或自定义策略(限制oss:PutObject到指定bucket/prefix/) - 过期时间建议设为900秒(15分钟),太长增加泄露风险,太短导致前端上传中途失效
- 返回的
credentials里SecurityToken必须原样传给前端,漏掉就报InvalidToken - Java SDK调用示例:
AssumeRoleRequest request = new AssumeRoleRequest() .setRoleArn("acs:ram::1234567890123456:role/oss-upload-role") .setRoleSessionName("upload-session-" + UUID.randomUUID()) .setDurationSeconds(900);
前端直传时Signature URL为什么总403
不是签名算法写错了,大概率是请求头、参数或策略没对齐。OSS直传依赖的是Post Policy,不是普通URL签名。
- 后端生成的
policy必须Base64编码,且内容含expiration(ISO8601格式)、conditions(比如限定bucket、key前缀、content-length-range) -
signature要用SecurityToken+AccessKeyId+SecretAccessKey三者参与HMAC-SHA1计算,缺一不可 - 前端构造
<form></form>时,key字段值不能带变量占位符(如${filename})却不在conditions里声明;否则OSS校验失败 - 常见错误现象:
ErrorCode: AccessDenied→ 检查policy是否过期或conditions不匹配;ErrorCode: InvalidPolicyDocument→ JSON格式非法或字段名拼错
Java后端生成Post Policy和签名的关键点
别手写JSON拼接policy,也别用String.getBytes()直接算签名——编码不一致会导致签名无效。
- 用
com.fasterxml.jackson.databind.ObjectMapper序列化policy对象,确保字段名小写、无空格、无换行 - 签名前对policy字符串做
UTF-8编码,再用Mac.getInstance("HmacSHA1")计算,密钥是SecretAccessKey + "&" + SecurityToken(注意&是字面量) - 返回给前端的字段必须包含:
accessid、host(如https://my-bucket.oss-cn-hangzhou.aliyuncs.com)、policy、signature、callback(如有)、success_action_status(推荐设为201) - 不要把
SecretAccessKey或SecurityToken写进日志,哪怕DEBUG级别
直传回调(Callback)配置踩坑最多
Callback不是可选功能,而是验证上传真实性的必要环节。跳过它等于放弃服务端验签。
立即学习“Java免费学习笔记(深入)”;
- Callback服务器必须能被公网访问(OSS会从阿里云机房发起POST请求),内网地址或localhost会失败
- 回调Body是JSON,但OSS默认发
application/x-www-form-urlencoded,需在policy里显式声明callback-var并解析原始Body - 后端收到Callback后,必须用
callbackBody+callbackVar+accessKeyId+accessKeySecret重新计算callbackSign,与Header中X-Oss-Callback-Signature比对 - 响应必须是JSON且HTTP状态码200,body里
{"status":"ok"}即可,多一个空格都可能让OSS认为回调失败
"Service": "sts.aliyuncs.com"),以及Callback签名验证时忘了把callbackVar里的$替换成实际值再参与计算。










