上传凭证
从安全角度考虑,NOS的上传服务都需要进行用户认证,无论是公开桶还是私有桶。因此,用户在使用直传服务的时候也需要构造认证信息。构造认证信息包括构造上传策略和计算上传凭证。下面所用到的AccessKey和SecretKey来进行签名验证,开通服务与AccessKey请参考 访问控制
上传策略
{
"Bucket" : "doc",
"Object" : "anne.jpg",
"Expires" : 1451491200,
"ObjectSizeMin": 126000,
"ObjectSizeMax": 128000,
"MimeLimit": "image/jpeg;image/png"
}
名称 | 描述 | 是否必须 |
---|---|---|
Bucket | 桶名 | 是 |
Object | 存储在NOS的对象名 | 是 |
Expires | 过期时间,(Unix时间),单位:秒 | 是 |
ObjectSizeMin | 限定上传对象大小的最小值,单位:Byte。对象大小小于该值会被判为上传失败,返回 400状态码 | 否 |
ObjectSizeMax | 限定上传对象大小的最大值,单位:Byte。对象大小大于该值会被判为上传失败,返回 400状态码 | 否 |
MimeLimit | 限定用户上传的对象类型。指定本字段值,服务器会根据ContentType指定的对象类型来匹配,如果匹配成功则上传,匹配失败则返回 400 状态码,说明该类型被限制上传。 | 否 |
OverWrite | 当OverWrite为true时,如存在同名文件则覆盖;反之,如存在则提示该对象已经存在,返回码为409。默认为true。 | 否 |
计算上传凭证
下面是一个最简策略:
{
"Bucket" : "doc",
"Object" : "anne.jpg",
"Expires" : 1451491200,
"ObjectSizeMin": 126000,
"ObjectSizeMax": 128000,
"MimeLimit": "image/jpeg;image/png"
}
我们根据这个上传策略可以进一步构造上传凭证,步骤为:
1.将上传策略转换为json格式
{"Bucket":"doc","Object":"anne.jpg","Expires":1451491200,"ObjectSizeMin": 126000,"ObjectSizeMax": 128000,"MimeLimit": image/jpeg;image/png}
2.对JSON编码的上传策略进行Base64编码,得到待签名字符串
encodedPutPolicy = base64_encode(putPolicy)
例如,对于以上事例,在Base64编码后,将得到:
eyJCdWNrZXQiOiJkb2MiLCJPYmplY3QiOiJhbm5lLmpwZyIsIkV4cGlyZXMiOjE0NTE0OTEyMDAsIk9iamVjdFNpemVNaW4iOiAxMjYwMDAsIk9iamVjdFNpemVNYXgiOiAxMjgwMDAsIm1pbWVMaW1pdCI6IGltYWdlL2pwZWc7aW1hZ2UvcG5nfQ==
3.使用SecertKey对上一步生成的待签名字符串计算HMAC-SHA1签名
sign = hmac_sha256(encodedPutPolicy, "<SecretKey>")
4.对签名进行Base64编码
encodedSign = base64_encode(sign)
例如,假设SecretKey = "SecretKey",则经过hmac_sha256签名并经过Base64编码之后得到:
v8Q5BNIJuEoi6zckOzPuC5hADL4t/zNaecakkk8STuE=
5.最终客户端在上传时,按以下方式填充 “x-nos-token” 头部
UPLOAD AccessKey:encodedSign:encodedPutPolicy
示例
如果上传策略为:{“Bucket”:”doc”,”Object”:”anne.jpg”,”Expires”:1451491200},AccessKey为:b6ff5ed65d1041e9a56e2257a2672990,SecretKey为: ae0208eea57c4bc9bc5754368c06a542.计算后对应的”x-nos-token”为:
UPLOAD b6ff5ed65d1041e9a56e2257a2672990:+SL08gyotpanS0qQdqugiWVdDSlsfrQr6YXUNw0Nkz4=:eyJCdWNrZXQiOiJkb2MiLCJPYmplY3QiOiJhbm5lLmpwZyIsIkV4cGlyZXMiOjE0NTE0OTEyMDB9
示例代码
# -*- coding: utf-8 -*- import base64 import hmac import hashlib accessKey = "your Accesskey" secretKey = "your SecretKey" putPolicy = '{"Bucket":"your Bucketname","Object":"your Objectname","Expires":1951491200}' #签名字符串 encodedPutPolicy = base64.b64encode(putPolicy) #对签名字符串计算HMAC-SHA256签名 signature = hmac.new(secretKey, encodedPutPolicy, digestmod=hashlib.sha256).digest(); #对签名进行Base64编码 encodedSign = base64.b64encode(signature) token = "UPLOAD " + accessKey + ":" + encodedSign + ":" + encodedPutPolicy print token
<?php $accessKey = "your Accesskey"; $secretKey = "your SecretKey"; $putPolicy = '{"Bucket":"your Bucketname","Object":"your Objectname","Expires":1951491200}'; #签名字符串 $encodedPutPolicy = base64_encode($putPolicy); #对签名字符串计算HMAC-SHA256签名 $signature = hash_hmac("sha256", $encodedPutPolicy, $secretKey, true); #对签名进行Base64编码 $encodedSign = base64_encode($signature); $token = "UPLOAD ".$accessKey.":".$encodedSign.":".$encodedPutPolicy; print $token; ?>
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import net.sf.json.JSONObject;
public class Token {
public static void main(String[] args){
String accessKey = "b6ff5ed65d1041e9a56e2257a2672990";
String secretKey = "ae0208eea57c4bc9bc5754368c06a542";
JSONObject putPolicy = new JSONObject();
putPolicy.put("Bucket", "doc");
putPolicy.put("Object", "anne.jpg");
putPolicy.put("Expires", 1451491200);
String encodedPutPolicy = new String(Base64.encodeBase64(putPolicy.toString().getBytes()));
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
//对签名字符串计算HMAC-SHA256签名
String encodedSign = Base64.encodeBase64String(sha256_HMAC.doFinal(encodedPutPolicy.getBytes()));
String token = "UPLOAD " + accessKey + ":" + encodedSign + ":" + encodedPutPolicy;
System.out.println(token);
}
catch (Exception e){
System.out.println("Error");
}
}
}
参数说明:
accessKey的值为用户的Access Key;
secretKey的值为用户的Access Secret;
Expires的值为超时时间点,需要晚于当前时间点。