3. 访问控制¶
3.1. 用户签名验证(Authentication)¶
NOS通过使用访问凭证ID(AccessKey)/访问凭证密钥(SecretKey)非对称加密的方法来验证某 个请求的发送者身份。AccessKey用于标识用户,SecretKey是用户用于加密签名字符串和NOS 用来验证签名字符串的密钥,其中SecretKey必须保密,只有用户和NOS知道。每个访问凭证 对都有active/inactive两种状态
- active表明用户可以用此ID对签名验证请求
- inactive表明用户暂停此ID对签名验证的功能
一个用户可以同时拥有多个active或者inactive的ID对。用户可以登录API KEY管理页面查看 管理访问凭证。当用户想以个人身份向NOS发送请求时,需要首先将发送的请求按照NOS指定 的格式生成签名字符串;然后使用SecretKey对签名字符串进行加密产生验证码。NOS收到请 求以后,会通过AccessKey找到对应的SecretKey,以同样的方法提取签名字符串和验证码, 如果计算出来的验证码和提供的一样即认为该请求是有效的;否则,NOS将拒绝处理这次请求 ,并返回相关的错误码。例如若AccessKey格式有误,返回错误码:InvalidAccessKeyId。
3.2. 在Head中包含签名¶
用户可以在HTTP请求头中增加Authorization(授权)来包含签名信息,表明这个请求已被授 权。如果用户的请求中没有Authentication字段,则认为是匿名访问。
3.2.1. 验证码计算¶
"Authorization: NOS " + AccessKey + ":" + Base64(HMAC-SHA256(HTTP-Verb + "\n"
+ Content-MD5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedHeaders
+ CanonicalizedResource))
- HTTP-Verb表示HTTP请求类型,如:PUT,GET,DELETE等
- Content-MD5表示内容数据的MD5值,某些API该字段非必须
- Content-Type表示内容的类型,某些API该字段非必须
- Date表示此次操作的时间,格式必须符合RFC1123的日期格式,示例:Wed, 01 Mar 2009 12:00:00 GMT
- CanonicalizedHeaders 表示请求中其他重要的HTTP头,构建方法见3.2.2节
- CanonicalizedResource 表示用户想要访问的NOS资源,构建方法见3.2.3节
其中,Date和CanonicalizedResource不能为空,其余字段如为空,用空字符串""
代
替;如果请求中的Date时间和NOS服务器的时间差正负15分钟以上,NOS服务器将拒绝该服务
,并返回错误码:AccessDenied。
3.2.2. 构建CanonicalizedHeaders的方法¶
所有以”x-nos-“为前缀的HTTP Header被称为CanonicalizedHeaders。它的构建方法如下:
- 将所有以”x-nos-“为前缀的HTTP请求头的key转换成小写字母。如”x-nos-meta-Name: Easyread”转换成”x-nos-meta-name: Easyread”。
- 如果有相同名字的请求头,则根据标准RFC 2616, 4.2章进行合并(两个值之间只用逗号分隔)。如有两个名为”x-nos-meta-name”的请求头,对应的值分别为”photo”和”Easyread”,则合并后为:”x-nos-meta-name:photo,Easyread”。注意:合并之后的顺序和请求头中出现的顺序一致
- 将上一步得到的所有HTTP请求头按照字典序进行升序排列。
- 删除请求头和内容之间分隔符两端出现的任何空格。如”x-nos-meta-name : photo,Easyread”转换成:”x-nos-meta-name:photo,Easyread”。
- 将所有的头和内容用
"\n"
分隔符分隔拼成最后的CanonicalizedHeader。
3.2.3. 构建CanonicalizedResource的方法¶
用户发送请求中想访问的NOS目标资源被称为CanonicalizedResource。它的构建方法如下:
- 将CanonicalizedResource置成空字符串
""
; - 放入要访问的NOS资源:对于ListBucket操作,资源为/;对于桶操作,资源为/BucketName/;对于对象操作,资源为/BucketName/ObjectName;
- 如果请求包含子资源(sub-resource),那么将所有子资源的Key按照字典序排列,并以”&”为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加”?”和子资源字符串。示例:/BucketName/ObjectName?partNumber=PartNumber&uploadId=UploadId
Attention
sub-resource,指的是NOS里面某些特殊的请求参数。NOS当前支持的子资源包括:”acl”, “location”, “uploadId”, “uploads”, “partNumber”, “delete”等
3.2.4. 在计算签名头的时候请遵循如下规则¶
- 用来签名的字符串为UTF-8格式,URL中的resource和queryString应该经过URL encode。
- 签名的方法用RFC 2104中定义的HMAC-SHA256方法,其中Key为Secretkey。
- Content-Type和Content-MD5在请求中不是必须的,但是如果请求需要签名验证,空值的话以回车符代替。
- 在所有非HTTP标准定义的header中,以”x-nos-“开头的header,都需要加入签名字符串。
- 以”x-nos-“开头的header在签名验证前需要符合以下规范:
- header的名字需要变成小写。
- header按字典序自小到大排序。
- 分割header name和value的冒号前后不能有空格。
- 每个Header之后都有一个回车,如果没有Header,CanonicalizedHeaders就设置为空。
3.2.5. 注意事项¶
- 如果传入的AccessKey不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。
- 若用户请求头中Authorization值的格式不对,返回403 Forbidden。错误码:InvalidAccessKeyId。
- 如果签名验证的时候,请求头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。
- 传入请求的时间必须在NOS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。
- 如果AccessKey是active的,但NOS判断用户的请求发生签名错误,则返回403 Forbidden,错误码AccessDenied。
- 计算签名的逻辑,可参看各类SDK源码 。
3.3. 在URL中包含签名¶
除了使用Authorization Header Http 头部之外,私有桶的访问外链用户还可以在URL中加入 签名信息,这样用户就可以把私有桶资源,以签名HTTP URL方式转给第三方实现授权访问。
3.3.1. URL中包含签名示例¶
http://nos.netease.com/myBucket/myObject?NOSAccessKeyId=b65d532bf4834789b5d38e394b47023d&Expires=1141889120&Signature=cjrwrMDR6xoP5jajz17ybSjvftQ%3D
在URL中实现签名,必须至少包含Signature,Expires,NOSAccessKeyId三个参数。Expires这个参数的值是一个UNIX时间(自UTC时间1970年1月1号开始的秒数), 用于标识该URL的超时时间。如果NOS接收到这个URL请求的时候晚于签名中包含的Expires参 数时,则返回请求超时的错误码。例如:当前时间是114189060,开发者希望创建一个60秒后 自动失效的URL,则可以设置Expires时间为1141889120。
所有NOS支持的请求和各种Header参数,在URL中进行签名的方法和上节介绍的签名算法基 本一样。主要区别如下:
- 通过URL包含签名时,之前的Date参数换成Expires参数。
- 对签名串做URL-Encode编码
- 对URL而言,Content-MD5、Content-Type等都是空串(
""
)
Signature = URL-Encode (Base64(HMAC-SHA256(HTTP-Verb + "\n"
+ Content-MD5 + "\n"
+ Content-Type + "\n"
+ Expires + "\n"
+ CanonicalizedHeaders
+ CanonicalizedResource))
其他注意事项:
- 不支持同时在URL和Head中包含签名。
- 如果传入的Signature,Expires,NOSAccessKeyId出现不止一次,以第一次为准。
- 请求先验证请求时间是否晚于Expires时间,然后再验证签名。
3.3.2. 注意事项¶
- 使用在URL中签名的方式,会将你授权的数据在过期时间以内曝露在互联网上,请预先评估使用风险。
- URL签名只支持GET请求下载Object。
- 在URL中添加签名时,Signature,Expires,NOSAccessKeyId顺序可以交换,但是如果Signature,Expires,NOSAccessKeyId缺少其中的一个或者多个,返回403 Forbidden。错误码:AccessDenied。
- 如果访问的当前时间晚于请求中设定的Expires时间,返回403 Forbidden。错误码:AccessDenied。
- 如果传入请求时间,必须在NOS服务器当前时间之后的15分钟以内。否则返回403 Forbidden。错误码:RequestTimeTooSkewed。
- 如果Expires时间格式错误,返回403 Forbidden。错误码:AccessDenied。
- 如果URL中包含参数Signature,Expires,NOSAccessKeyId中的一个或者多个,并且Head中也包含签名消息,返回消息400 Bad Request。错误码:InvalidArgument。
- 生成URL中的签名字符串时,除Date被替换成Expires参数外,仍然包含content-type、content-md5、CanonicalizedHeaders、CanonicalizedResource等上节中定义的Header。(请求中虽然仍然有Date这个请求头,但不需要将Date加入签名字符串中)
3.4. Bucket权限控制¶
NOS提供Bucket级别的权限访问控制,Bucket目前有两种访问权限:Public-read和Private,它们的含义如下:
- Public-read:只有该Bucket的创建者可以对该Bucket内的Object进行写操作(包括Put和Delete Object);任何人(包括匿名访问)可以对该Bucket中的Object进行读操作(Get Object)。
- Private:只有该Bucket的创建者可以对该Bucket内的Object进行读写操作(包括Put、Delete和Get Object);其他人无法访问该Bucket内的Object。
用户新创建一个Bucket时,如果不指定Bucket权限,NOS会自动为该Bucket设置Private权限。对于一个已经存在的Bucket,只有它的创建者可以修改该Bucket的权限。
3.5. Object外链地址的构成规则¶
如果一个Bucket设置成Public-read权限,意味着你允许其他用户来访问属于你的Object。你的Object的外链地址构成规则如下:
http://<你的Bucket名字>.endpoint/<你的Object名字>
例如,在一个杭州分区Bucket(名字为photo)中,放了名为一个”image/test.jpg”的Object,那么这个Object的URL为:
http://photo.nos-eastchina1-i.netease.com/image/test.jpg
photo是Bucket
nos-eastchina1-i.netease.com为杭州分区的访问域名
image/test.jpg是Object
用户可以将该URL链接放入HTML中:
<img src=”http://photo.nos-eastchina1-i.netease.com/image/test.jpg” />