华为云用户手册

  • 功能介绍 创建桶是指按照用户指定的桶名创建一个新桶的操作。 默认情况下,一个用户可以拥有的桶的数量不能超过100个。 用户删除桶后,需要等待30分钟才能创建同名桶和并行文件系统。 OBS支持在创建桶时指定桶的AZ类型,您可以开启或关闭多AZ。关闭多AZ时,桶内数据默认存储在单个AZ内;开启多AZ时,桶内数据冗余存储在多个AZ内,可靠性更高。旧桶AZ类型默认为单AZ。 OBS支持在创建桶时打开桶级WORM开关,打开后可以为桶内的对象设置WORM,详见配置桶级默认WORM策略。注意:WORM开关只能在创建桶时打开,一旦打开无法关闭;在打开WORM开关的时候会默认为桶开启多版本,且多版本状态无法关闭;您无法为一个桶同时开启WORM开关和并行文件系统。 新创建桶的桶名在OBS中必须是唯一的。如果是同一个用户重复创建同一区域的同名桶时返回成功。除此以外的其他场景重复创建同名桶返回桶已存在。用户可以在请求消息头中加入x-obs-acl等参数,设置要创建桶的权限控制策略。
  • 请求消息头 该操作消息头与普通请求一样,请参见表3,但可以带附加消息头,附加请求消息头如下所示。 表1 附加请求消息头 消息头名称 消息头类型 是否必选 描述 x-obs-acl String 否 参数解释: 创建桶时,可以加上此消息头设置桶的权限控制策略,使用的策略为预定义的ACL策略。 取值范围: private:桶或对象的所有者拥有完全控制的权限,其他任何人都没有访问权限。 public-read:设置在桶上时,所有人可以获取该桶内对象列表、桶内多段任务、桶的元数据。 public-read-write:设在桶上,所有人可以获取该桶内对象列表、桶内多段任务、桶的元数据、上传对象、删除对象、初始化段任务、上传段、合并段、拷贝段、取消多段上传任务。 public-read-delivered:设在桶上,所有人可以获取该桶内对象列表、桶内多段任务、桶的元数据,可以获取该桶内对象的内容和元数据。 public-read-write-delivered:设在桶上,所有人可以获取该桶内对象列表、桶内多段任务、桶的元数据、上传对象、删除对象、初始化段任务、上传段、合并段、拷贝段、取消多段上传任务,可以获取该桶内对象的内容和元数据。 bucket-owner-full-control:设在对象上,桶和对象的所有者拥有对象的完全控制权限,其他任何人都没有访问权限。 默认情况下,上传对象至其他用户的桶中,桶拥有者没有对象的控制权限。对象拥有者为桶拥有者添加此权限控制策略后,桶所有者可以完全控制对象。 例如,用户A上传对象x至用户B的桶中,系统默认用户B没有对象x的控制权。当用户A为对象x设置bucket-owner-full-control策略后,用户B就拥有了对象x的控制权。 默认取值: private x-obs-storage-class String 否 参数解释: 创建桶时,可以加上此消息头设置桶的默认存储类型。 取值范围: STANDARD(标准存储) WARM(低频访问存储) COLD(归档存储) DEEP_ARCHIVE(深度归档存储) 默认取值: STANDARD x-obs-grant-read String 否 参数解释: 授权READ权限给指定domain下的所有用户。允许列举桶内对象、列举桶中多段任务、列举桶中多版本对象、获取桶元数据。 示例:x-obs-grant-read:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、 IAM 用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-grant-write String 否 参数解释: 授权WRITE权限给指定domain下的所有用户,允许创建、删除、覆盖桶内所有对象,允许初始化段、上传段、拷贝段、合并段、取消多段上传任务。 示例:x-obs-grant-write:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、IAM用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-grant-read-acp String 否 参数解释: 授权READ_ACP权限给指定domain下的所有用户,允许读桶的ACL信息。 示例:x-obs-grant-read-acp:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、IAM用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-grant-write-acp 字符串 否 参数解释: 授权WRITE_ACP权限给指定domain下的所有用户,允许修改桶的ACL信息。 示例:x-obs-grant-write-acp:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、IAM用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-grant-full-control 字符串 否 参数解释: 授权FULL_CONTROL权限给指定domain下的所有用户。 示例:x-obs-grant-full-control:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、IAM用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-grant-read-delivered String 否 参数解释: 授权READ权限给指定domain下的所有用户,并且在默认情况下,该READ权限将传递给桶内所有对象。 示例:x-obs-grant-read-delivered:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、IAM用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-grant-full-control-delivered String 否 参数解释: 授权FULL_CONTROL权限给指定domain下的所有用户,并且在默认情况下,该FULL_CONTROL权限将传递给桶内所有对象。 示例:x-obs-grant-full-control-delivered:id=租户id 约束限制: 无 取值范围: id=租户id,获取方式请参考获取账号、IAM用户、项目、用户组、区域、委托的名称和ID。 默认取值: 无 x-obs-az-redundancy String 否 参数解释: 创建桶时带上此消息头设置桶的存储类型为多AZ,不携带时默认为单AZ。示例:x-obs-az-redundancy:3az 约束限制: 用户携带该头域指定新创的桶的存储类型为多AZ,存在一种情况是当该区域如果不支持多AZ存储,则该桶的存储类型仍为单AZ。 取值范围: 3az 默认取值: 指定头域时必须为3az,无默认取值。不指定头域,默认为单AZ。 x-obs-fs-file-interface String 否 参数解释: 创建桶时可以带上此消息头以创建并行文件系统。 示例:x-obs-fs-file-interface:Enabled 取值范围: Enabled 默认取值: 指定头域时必须为Enabled,无默认取值。 x-obs-epid String 否 参数解释: 企业项目ID。开通企业项目的用户可以从企业项目服务获取,格式为uuid,默认项目传“0”或者不带该头域,未开通企业项目的用户可以不带该头域。 示例:x-obs-epid:9892d768-2d13-450f-aac7-ed0e44c2585f 约束限制: 无 取值范围: 填写正确的企业项目ID或者为ID为0。 默认取值: 0 x-obs-bucket-type String 否 参数解释: 创建桶时可以带上此消息头指定创建的桶类型,桶类型包括OBS桶和文件桶。 示例:x-obs-bucket-type:OBJECT 约束限制: 无 取值范围: OBJECT:对象存储桶。 POSIX:并行文件系统。 默认取值: 指定头域时必须手动指定取值,无默认取值。不指定头域时,默认为OBJECT。 x-obs-bucket-object-lock-enabled String 否 参数解释: 创建桶时可以带上此消息头来开启WORM开关。 示例:x-obs-bucket-object-lock-enabled:true 约束限制: 只支持对象桶。 取值范围: true:开启WORM开关 默认取值: 指定头域时必须为true,无默认取值。不指定头域时,不开启WORM。 x-obs-server-side-encryption String 否 参数解释: 创建桶时可以带上此头域来指定桶加密配置的加密模式。 示例:x-obs-server-side-encryption: kms 约束限制: 无 取值范围: kms obs 默认取值: 指定头域时必须指定对应的值,无默认值。不指定头域时不开启桶加密。 x-obs-server-side-data-encryption String 否 参数解释: 创建桶时带上此头域来指定服务端加密配置的加密算法。 示例:x-obs-server-side-data-encryption: AES256 约束限制: 无 取值范围: AES256 SM4 当携带了x-obs-server-side-encryption:kms,该头域可选 AES256、SM4; 当携带了x-obs-server-side-encryption:obs,该头域可选 AES256。 默认取值: 无 x-obs-server-side-encryption-kms-key-id String 如果携带了x-obs-server-side-encryption: kms,该头域可选。 参数描述: 当加密方式为SSE-KMS且使用指定密钥加密时,需输入密钥ID。密钥ID获取方法请参见查看密钥。 类型:String 约束限制: 当您设置了x-obs-server-side-encryption头域且赋值为“kms”,即选择kms加密方式时,才能使用该头域指定加密密钥。 默认取值: 当您选择使用kms加密方式,但未设置此头域时,默认的主密钥将会被使用。如果默认主密钥不存在,系统将默认创建并使用。 x-obs-sse-kms-key-project-id String 如果未携带x-obs-server-side-encryption-kms-key-id,则不能携带该头域。 参数解释: SSE-KMS加密方式下KMS主密钥所属的项目ID(非企业项目ID)。 约束限制: 无 取值范围: 与x-obs-server-side-encryption-kms-key-id指定的KMSMasterKeyID相匹配的项目ID(非企业项目ID)。 默认取值: 无
  • 请求消息头 该操作消息头与普通请求一样,请参见表3,但可以带附加消息头,附加请求消息头如下所示。 表1 附加请求消息头 消息头名称 描述 是否必选 x-obs-bucket-type 通过此消息头明确获取的列表内容。 取值: OBJECT:获取所有桶列表。 POSIX:获取所有并行文件系统列表。 不带此消息头则获取所有桶和并行文件系统列表。 示例:x-obs-bucket-type: POSIX 否
  • 响应消息元素 该请求的响应消息中,会以XML形式将用户拥有的桶列出来,元素的具体含义如表2所示。 表2 响应消息元素 元素名称 描述 ListAllMyBucketsResult 用户的桶列表。 类型:XML Owner 桶拥有者信息,包含租户ID。 类型:XML ID 用户的DomainID(账号ID)。 类型:String Buckets 用户所拥有的桶列表。 类型:XML Bucket 具体的桶信息。 类型:XML Name 桶名称。 类型:String CreationDate 桶的创建时间。 类型:String Location 桶的位置信息。 类型:String BucketType 桶类型。 类型:String OBJECT:对象存储桶。 POSIX:并行文件系统。
  • 请求示例 1 2 3 4 5 6 GET / HTTP/1.1 User-Agent: curl/7.29.0 Host: obs.cn-north-4.myhuaweicloud.com Accept: */* Date: Mon, 25 Jun 2018 05:37:12 +0000 Authorization: OBS GKDF4C7Q6SI0IPGTXTJN:9HXkVQIiQKw33UEmyBI4rWrzmic=
  • 向cn-north-4区域的桶bucket001中上传对象,名称为objecttest1 示例中使用通用的Apache Http Client。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 package com.obsclient; import java.io.*; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; public class TestMain { /* 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。*/ public static String accessKey = System.getenv("HUAWEICLOUD_SDK_AK"); //取值为获取的AK public static String securityKey = System.getenv("HUAWEICLOUD_SDK_SK"); //取值为获取的SK public static void main(String[] str) { putObjectToBucket(); } private static void putObjectToBucket() { InputStream inputStream = null; CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse httpResponse = null; String requestTime = DateUtils.formatDate(System.currentTimeMillis()); HttpPut httpPut = new HttpPut("http://bucket001.obs.cn-north-4.myhuaweicloud.com/objecttest1"); httpPut.addHeader("Date", requestTime); /** 根据请求计算签名 **/ String contentMD5 = ""; String contentType = ""; String canonicalizedHeaders = ""; String canonicalizedResource = "/bucket001/objecttest1"; // Content-MD5 、Content-Type 没有直接换行, data格式为RFC 1123,和请求中的时间一致 String canonicalString = "PUT" + "\n" + contentMD5 + "\n" + contentType + "\n" + requestTime + "\n" + canonicalizedHeaders + canonicalizedResource; System.out.println("StringToSign:[" + canonicalString + "]"); String signature = null; try { signature = Signature.signWithHmacSha1(securityKey, canonicalString); // 上传的文件目录 inputStream = new FileInputStream("D:\\OBSobject\\text01.txt"); InputStreamEntity entity = new InputStreamEntity(inputStream); httpPut.setEntity(entity); // 增加签名头域 Authorization: OBS AccessKeyID:signature httpPut.addHeader("Authorization", "OBS " + accessKey + ":" + signature); httpResponse = httpClient.execute(httpPut); // 打印发送请求信息和收到的响应消息 System.out.println("Request Message:"); System.out.println(httpPut.getRequestLine()); for (Header header : httpPut.getAllHeaders()) { System.out.println(header.getName() + ":" + header.getValue()); } System.out.println("Response Message:"); System.out.println(httpResponse.getStatusLine()); for (Header header : httpResponse.getAllHeaders()) { System.out.println(header.getName() + ":" + header.getValue()); } BufferedReader reader = new BufferedReader(new InputStreamReader( httpResponse.getEntity().getContent())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = reader.readLine()) != null) { response.append(inputLine); } reader.close(); // print result System.out.println(response.toString()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } } 其中Date头域DateUtils的格式为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.obsclient; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; public class DateUtils { public static String formatDate(long time) { DateFormat serverDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH); serverDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); return serverDateFormat.format(time); } } 签名字符串Signature的计算方法为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.obsclient; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.util.Base64; public class Signature { public static String signWithHmacSha1(String sk, String canonicalString) throws UnsupportedEncodingException { try { SecretKeySpec signingKey = new SecretKeySpec(sk.getBytes("UTF-8"), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(signingKey); return Base64.getEncoder().encodeToString(mac.doFinal(canonicalString.getBytes("UTF-8"))); } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) { e.printStackTrace(); } return null; } }
  • 获取cn-north-4区域的桶列表 示例中使用通用的Apache Http Client。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 package com.obsclient; import java.io.*; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; public class TestMain { /* 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。*/ public static String accessKey = System.getenv("HUAWEICLOUD_SDK_AK"); //取值为获取的AK public static String securityKey = System.getenv("HUAWEICLOUD_SDK_SK"); //取值为获取的SK public static void main(String[] str) { listAllMyBuckets(); } private static void listAllMyBuckets() { CloseableHttpClient httpClient = HttpClients.createDefault(); String requesttime = DateUtils.formatDate(System.currentTimeMillis()); HttpGet httpGet = new HttpGet("http://obs.cn-north-4.myhuaweicloud.com"); httpGet.addHeader("Date", requesttime); /** 根据请求计算签名**/ String contentMD5 = ""; String contentType = ""; String canonicalizedHeaders = ""; String canonicalizedResource = "/"; // Content-MD5 、Content-Type 没有直接换行, data格式为RFC 1123,和请求中的时间一致 String canonicalString = "GET" + "\n" + contentMD5 + "\n" + contentType + "\n" + requesttime + "\n" + canonicalizedHeaders + canonicalizedResource; System.out.println("StringToSign:[" + canonicalString + "]"); String signature = null; try { signature = Signature.signWithHmacSha1(securityKey, canonicalString); // 增加签名头域 Authorization: OBS AccessKeyID:signature httpGet.addHeader("Authorization", "OBS " + accessKey + ":" + signature); CloseableHttpResponse httpResponse = httpClient.execute(httpGet); // 打印发送请求信息和收到的响应消息 System.out.println("Request Message:"); System.out.println(httpGet.getRequestLine()); for (Header header : httpGet.getAllHeaders()) { System.out.println(header.getName() + ":" + header.getValue()); } System.out.println("Response Message:"); System.out.println(httpResponse.getStatusLine()); for (Header header : httpResponse.getAllHeaders()) { System.out.println(header.getName() + ":" + header.getValue()); } BufferedReader reader = new BufferedReader(new InputStreamReader( httpResponse.getEntity().getContent())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = reader.readLine()) != null) { response.append(inputLine); } reader.close(); // print result System.out.println(response.toString()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } } 其中Date头域DateUtils的格式为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.obsclient; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; public class DateUtils { public static String formatDate(long time) { DateFormat serverDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH); serverDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); return serverDateFormat.format(time); } } 签名字符串Signature的计算方法为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.obsclient; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.util.Base64; public class Signature { public static String signWithHmacSha1(String sk, String canonicalString) throws UnsupportedEncodingException { try { SecretKeySpec signingKey = new SecretKeySpec(sk.getBytes("UTF-8"), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(signingKey); return Base64.getEncoder().encodeToString(mac.doFinal(canonicalString.getBytes("UTF-8"))); } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) { e.printStackTrace(); } return null; } }
  • 响应消息头 对应请求消息头,响应同样也有消息头,如“Content-Length”。 详细的公共响应消息头字段请参见表1。 表1 公共响应消息头 消息头名称 描述 Content-Length 响应消息体的字节长度。 类型:String 默认值:无。 Connection 指明与服务器的连接是长连接还是短连接。 类型:String 有效值:keep-alive | close。 默认值:无。 Date OBS系统响应的时间。 类型:String 默认值:无。 ETag 对象的base64编码的128位MD5摘要。ETag是对象内容的唯一标识,可以通过该值识别对象内容是否有变化。比如上传对象时ETag为A,下载对象时ETag为B,则说明对象内容发生了变化。实际的ETag是对象的哈希值。ETag只反映变化的内容,而不是其元数据。上传的对象或拷贝操作创建的对象,通过MD5加密后都有唯一的ETag。如果通过多段上传对象,则无论加密方法如何,MD5会拆分ETag,此类情况ETag就不是MD5的摘要。 类型:String x-obs-id-2 帮助定位问题的特殊符号。 类型:String 默认值:无。 x-reserved-indicator 帮助定位问题的特殊符号。 类型:String 默认值:无。 x-obs-request-id 由OBS创建来唯一确定本次请求的值,可以通过该值来定位问题。 类型:String 默认值:无。
  • 请求和Policy示例 下面的几张表提供了一些请求和Policy的例子。 示例1:在examplebucket桶中上传testfile.txt对象,并且设置对象ACL为公共可读。 请求 policy POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=7e32233530b26 Content-Length: 1250 --7e32233530b26 Content-Disposition: form-data; name="key" testfile.txt --7e32233530b26 Content-Disposition: form-data; name="x-obs-acl" public-read --7e32233530b26 Content-Disposition: form-data; name="content-type" text/plain --7e32233530b26 Content-Disposition: form-data; name="AccessKeyId" UDSIAMSTUBTEST000002 --7e32233530b26 Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMTktMDctMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0IiB9LAogICAgWyJlcSIsICIka2V5IiwgInRlc3RmaWxlLnR4dCJdLAoJeyJ4LW9icy1hY2wiOiAicHVibGljLXJlYWQiIH0sCiAgICBbImVxIiwgIiRDb250ZW50LVR5cGUiLCAidGV4dC9wbGFpbiJdLAogICAgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDYsIDEwXQogIF0KfQo= --7e32233530b26 Content-Disposition: form-data; name="Signature" xxl7bZs/5FgtBUggOdQ88DPZUo0= --7e32233530b26 Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 --7e32233530b26 Content-Disposition: form-data; name="submit" Upload --7e32233530b26-- { "expiration": "2019-07-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket" }, ["eq", "$key", "testfile.txt"], {"x-obs-acl": "public-read" }, ["eq", "$Content-Type", "text/plain"] ] } 示例2:在examplebucket桶中上传file/obj1对象,并且设置对象的四个自定义元数据。 请求 policy POST / HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com Content-Type: multipart/form-data; boundary=7e329d630b26 Content-Length: 1597 --7e3542930b26 Content-Disposition: form-data; name="key" file/obj1 --7e3542930b26 Content-Disposition: form-data; name="AccessKeyId" UDSIAMSTUBTEST000002 --7e3542930b26 Content-Disposition: form-data; name="policy" ewogICJleHBpcmF0aW9uIjogIjIwMTktMDctMDFUMTI6MDA6MDAuMDAwWiIsCiAgImNvbmRpdGlvbnMiOiBbCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0IiB9LAogICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgImZpbGUvIl0sCiAgICB7Ingtb2JzLW1ldGEtdGVzdDEiOiJ2YWx1ZTEifSwKICAgIFsiZXEiLCAiJHgtb2JzLW1ldGEtdGVzdDIiLCAidmFsdWUyIl0sCiAgICBbInN0YXJ0cy13aXRoIiwgIiR4LW9icy1tZXRhLXRlc3QzIiwgImRvYyJdLAogICAgWyJzdGFydHMtd2l0aCIsICIkeC1vYnMtbWV0YS10ZXN0NCIsICIiXQogIF0KfQo= --7e3542930b26 Content-Disposition: form-data; name="Signature" HTId8hcaisn6FfdWKqSJP9RN4Oo= --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test1" value1 --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test2" value2 --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test3" doc123 --7e3542930b26 Content-Disposition: form-data; name="x-obs-meta-test4" my --7e3542930b26 Content-Disposition: form-data; name="file"; filename="E:\TEST_FILE\TEST.txt" Content-Type: text/plain 123456 --7e3542930b26 Content-Disposition: form-data; name="submit" Upload --7e3542930b26-- { "expiration": "2019-07-01T12:00:00.000Z", "conditions": [ {"bucket": "examplebucket" }, ["starts-with", "$key", "file/"], {"x-obs-meta-test1":"value1"}, ["eq", "$x-obs-meta-test2", "value2"], ["starts-with", "$x-obs-meta-test3", "doc"], ["starts-with", "$x-obs-meta-test4", ""] ] }
  • 签名算法 表单中携带签名的计算公式如下: Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, StringToSign ) ) StringToSign = Base64( UTF-8-Encoding-Of( policy ) ) 签名的计算过程如下: 构造请求字符串StringToSign,即对policy先进行UTF8编码,然后再进行Base64编码。 使用SK第一步结果进行HMAC-SHA1签名计算。 对第二步的结果进行Base64编码,得到签名。 图1 计算表单签名
  • 步骤一:创建policy 下面将以如下policy为例介绍policy的组成和语法。下方的policy限制了签名的有效时间为2024年12月31日12点之后无效,上传对象的访问权限限制为公共读,请求消息头中的x-obs-security-token须等于"YwkaRTbdY8g7q...." },对象上传的桶名需要为“book”,对象名必须以前缀“user/”开头: 1 2 3 4 5 6 7 8 { "expiration": "2024-12-31T12:00:00.000Z", "conditions": [ {"x-obs-acl": "public-read" }, {"x-obs-security-token": "YwkaRTbdY8g7q...." }, {"bucket": "book" }, ["starts-with", "$key", "user/"] ] } Policy策略中由有效时间有效时间:Expiration和条件元素条件元素:Conditions两部分组成。
  • 条件元素:Conditions 使用Conditions可以要求调用请求必须满足指定的条件限制。示例中的条件要求请求的桶名必须是book,对象名必须以user/为前缀,对象的acl必须是公共可读。policy可以限制除了AccessKeyId、Signature、file、policy、token、前缀为"x-ignore-"的字段外的其他所有表单项。下表是conditions中可校验的元素: 表2 policy中可以包含的条件元素 元素名称 元素类型 描述 支持的匹配方式 x-obs-acl String 请求中的ACL。 精确匹配:Exact Matches 前缀匹配:starts-with content-length-range int 设置上传对象的最大和最小长度。例如: 1 ["content-length-range", 1048576, 10485760] 范围匹配:Specifying Ranges Cache-Control, Content-Type, Content-Disposition, Content-Encoding, Expires String REST请求特定头域。 精确匹配:Exact Matches 前缀匹配:starts-with key String 上传对象的名字。 精确匹配:Exact Matches 前缀匹配:starts-with bucket String 请求桶名。 精确匹配:Exact Matches success_action_redirect String 上传对象成功后重定向的URL地址。具体描述请参见5.4.2-POST上传。 精确匹配:Exact Matches 前缀匹配:starts-with success_action_status String 如果未指定success_action_redirect,则成功上传时返回给客户端的状态码。具体描述请参见5.4.2-POST上传。 精确匹配:Exact Matches x-obs-meta-* String 用户自定义元数据。 元素中的关键字不允许含有非ASCII码或不可识别字符,如果一定要使用非ASCII码或不可识别字符,需要客户端自行做编解码处理,可以采用URL编码或者Base64编码,服务端不会做解码处理。 精确匹配:Exact Matches 前缀匹配:starts-with x-obs-* String 其他以x-obs-为前缀的头域。 精确匹配:Exact Matches 前缀匹配:starts-with x-obs-security-token String 请求消息头中字段名。 临时AK/SK和securitytoken鉴权必加字段名。如何获取临时AK/SK和securitytoken请参考通过token获取临时访问密钥和securitytoken。 精确匹配:Exact Matches Policy条件匹配的方式如下: 表3 policy条件匹配方式 匹配方式 描述 精确匹配(Exact Matches) 默认是完全匹配,POST表单中该项的值必须和policy的conditions中设置的值完全一样。例如:上传对象的同时设置对象ACL为public-read,表单中x-obs-acl元素的值为public-read,policy中的conditions可以设置为 1 {"x-obs-acl": "public-read" } 或者另一种等效的格式: 1 [ "eq", "$x-obs-acl", "public-read"] 前缀匹配(Starts With) 如果使用该条件,则post表单中对应元素的值必须是固定字符串开始。例如:上传对象名以user/为前缀,表单中key元素的值可以是user/test1、user/test2,policy的conditions中该条件如下: 1 ["starts-with", "$key", "user/"] 任意匹配(Matching Any Content) post表单中对应元素的值可以是任意值。例如:请求成功后重定向的地址可以是任意地址,表单中success_action_redirect元素的值可以是任意值,policy的conditions中该条件如下: 1 ["starts-with", "$success_action_redirect", ""] 范围匹配(Specifying Ranges) post表单中file元素文件的内容长度可以是一个指定的范围,只用于限制对象大小。例如上传对象大小为1-10MB,表单中file元素的内容长度可以是1048576-10485760,policy的conditions中该条件如下,注意值没有双引号: 1 ["content-length-range", 1048576, 10485760] policy使用json格式,conditions可以支持 { } 和 [ ] 两种方式,{ }中包含表单元素的key和value两项,以冒号分隔;[ ]中包含条件类型、key、value三项,以逗号分隔,元素key之前使用$字符表示变量。 Policy中必须转义的字符如下: 表4 policy中必须转义的字符 转义后的字符 真实字符 \\ 反斜杠(\) \$ 美元符号($) \b 退格 \f 换页 \n 换行 \r 回车 \t 水平制表 \v 垂直制表 \uxxxx 所有Unicode字符
  • 功能介绍 OBS服务支持基于浏览器的POST上传对象请求,此类请求的签名信息通过表单的方式上传。计算POST表单上传请求的签名,需要先定义一个安全策略(policy),这个安全策略的作用是限制表单上传的内容,例如规定表单上传对象的对象名前缀必须以“prefix01”开头,使用policy能够帮助您更好的管控桶中的文件。POST上传对象的流程是: 创建一个policy,指定请求中需要满足的条件,比如:桶名、对象名前缀。 计算基于此policy的签名。 创建一个表单,表单中必须包含有效的签名和policy,使用该表单将对象上传到桶中。
  • 有效时间:Expiration 表1 有效时间Expiration 参数名称 参数类型 是否必选 描述 Expiration String 必选 参数解释: 描述本次签名的有效时间。如示例中"expiration": "2024-12-31T12:00:00.000Z"表示请求在2024年12月31日12点之后无效。 约束限制: 格式为ISO 8601 UTC,"yyyy-MM-dd'T'HH:mm:ss'Z'"或"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"。 取值范围: 不涉及 默认取值: 无
  • 功能介绍 OBS服务支持用户构造一个特定操作的URL,这个URL的Query参数中会包含用户AK、签名、有效期等信息,任何拿到这个URL的人均可执行这个操作,OBS服务收到这个请求后认为该请求就是签发URL用户自己在执行操作。例如构造一个携带签名信息的下载对象的URL,拿到相应URL的人都能下载这个对象,但该URL只在Expires指定的失效时间内有效。URL中携带签名主要用于在不提供给其他人Secret Access Key的情况下,让其他人能用预签发的URL来进行身份认证,并执行预定义的操作。 URL中携带签名请求的示例如下: GET /ObjectKey?AccessKeyId=AccessKeyID&Expires=ExpiresValue&Signature=signature HTTP/1.1 Host: bucketname.obs.cn-north-4.myhuaweicloud.com URL中使用临时AK,SK和securitytoken下载对象消息格式如下: GET /ObjectKey?AccessKeyId=AccessKeyID&Expires=ExpiresValue&Signature=signature&x-obs-security-token=securitytoken HTTP/1.1 Host: bucketname.obs.cn-north-4.myhuaweicloud.com
  • StringToSign构造示例 表4 下载对象在URL中携带签名的请求及StringToSign 请求消息头 StringToSign GET /objectkey?AccessKeyId=MFyfvK41ba2giqM7Uio6PznpdUKGpownRZlmVmHc&Expires=1532779451&Signature=0Akylf43Bm3mD1bh2rM3dmVp1Bo%3D HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com GET \n \n \n 1532779451\n /examplebucket/objectkey 表5 在URL中使用临时AK/SK和securitytoken下载对象请求及StringToSign 请求消息头 StringToSign GET /objectkey?AccessKeyId=MFyfvK41ba2giqM7Uio6PznpdUKGpownRZlmVmHc&Expires=1532779451&Signature=0Akylf43Bm3mD1bh2rM3dmVp1Bo%3D&x-obs-security-token=YwkaRTbdY8g7q.... HTTP/1.1 Host: examplebucket.obs.cn-north-4.myhuaweicloud.com GET \n \n \n 1532779451\n /examplebucket/objectkey?x-obs-security-token=YwkaRTbdY8g7q....
  • 签名不匹配报错处理 如果调用OBS API报如下错误: 状态码:403 Forbidden 错误码:SignatureDoesNotMatch 错误信息:The request signature we calculated does not match the signature you provided. Check your key and signing method. 请参考以下案例进行排查处理:签名不匹配(SignatureDoesNotMatch)如何处理
  • 使用URL携带签名方式为浏览器生成预定义的URL 计算出签名,然后将Host作为URL的前缀,可以生成预定义的URL,如下面的示例所示,在浏览器中直接输入该地址则可以下载examplebucket桶中的objectkey对象。这个链接的有效期是1532779451(Sat Jul 28 20:04:11 CS T 2024)。 http(s)://examplebucket.obs.cn-north-4.myhuaweicloud.com/objectkey?AccessKeyId=AccessKeyID&Expires=1532779451&Signature=0Akylf43Bm3mD1bh2rM3dmVp1Bo%3D 在Linux环境上使用curl命令访问注意&字符需要\转义,如下命令将对象objectkey下载到output文件中: curl http(s)://examplebucket.obs.cn-north-4.myhuaweicloud.com/objectkey?AccessKeyId=AccessKeyID\&Expires=1532779451\&Signature=0Akylf43Bm3mD1bh2rM3dmVp1Bo%3D -X GET -o output
  • 签名不匹配报错处理 如果调用OBS API报如下错误: 状态码:403 Forbidden 错误码:SignatureDoesNotMatch 错误信息:The request signature we calculated does not match the signature you provided. Check your key and signing method. 请参考以下案例进行排查处理:签名不匹配(SignatureDoesNotMatch)如何处理
  • StringToSign构造示例 以下是生成StringToSign的示例: 表4 获取对象 请求消息头 StringToSign GET /object.txt HTTP/1.1 Host: bucket.obs.cn-north-4.myhuaweicloud.com Date: Sat, 12 Oct 2015 08:12:38 GMT GET \n \n \n Sat, 12 Oct 2015 08:12:38 GMT\n /bucket/object.txt 表5 使用临时AK/SK和securitytoken上传对象 请求消息头 StringToSign PUT /object.txt HTTP/1.1 User-Agent: curl/7.15.5 Host: bucket.obs.cn-north-4.myhuaweicloud.com x-obs-date:Tue, 15 Oct 2015 07:20:09 GMT x-obs-security-token: YwkaRTbdY8g7q.... content-type: text/plain Content-Length: 5913339 PUT\n \n text/plain\n \n x-obs-date:Tue, 15 Oct 2015 07:20:09 GMT\n x-obs-security-token:YwkaRTbdY8g7q....\n /bucket/object.txt 表6 带请求头字段上传对象 请求消息头 StringToSign PUT /object.txt HTTP/1.1 User-Agent: curl/7.15.5 Host: bucket.obs.cn-north-4.myhuaweicloud.com Date: Mon, 14 Oct 2015 12:08:34 GMT x-obs-acl: public-read content-type: text/plain Content-Length: 5913339 PUT\n \n text/plain\n Mon, 14 Oct 2015 12:08:34 GMT\n x-obs-acl:public-read\n /bucket/object.txt 表7 获取对象ACL 请求消息头 StringToSign GET /object.txt?acl HTTP/1.1 Host: bucket.obs.cn-north-4.myhuaweicloud.com Date: Sat, 12 Oct 2015 08:12:38 GMT GET \n \n \n Sat, 12 Oct 2015 08:12:38 GMT\n /bucket/object.txt?acl 表8 上传对象且携带Content-MD5头域 请求消息头 StringToSign PUT /object.txt HTTP/1.1 Host: bucket.obs.cn-north-4.myhuaweicloud.com x-obs-date:Tue, 15 Oct 2015 07:20:09 GMT Content-MD5: I5pU0r4+sgO9Emgl1KMQUg== Content-Length: 5913339 PUT\n I5pU0r4+sgO9Emgl1KMQUg==\n \n \n x-obs-date:Tue, 15 Oct 2015 07:20:09 GMT\n /bucket/object.txt 表9 使用自定义 域名 方式上传对象 请求消息头 StringToSign PUT /object.txt HTTP/1.1 Host: obs.ccc.com x-obs-date:Tue, 15 Oct 2015 07:20:09 GMT Content-MD5: I5pU0r4+sgO9Emgl1KMQUg== Content-Length: 5913339 PUT\n I5pU0r4+sgO9Emgl1KMQUg==\n \n \n x-obs-date:Tue, 15 Oct 2015 07:20:09 GMT\n /obs.ccc.com/object.txt
  • Java中Content-MD5的计算方法示例 您可以选择在构造StringToSign时加入Content-MD5的头域和头域值,以下为计算Content-MD5头域值的代码示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import java.security.MessageDigest; import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; public class Md5{ public static void main(String[] args) { try { String exampleString = "blog"; MessageDigest messageDigest = MessageDigest.getInstance("MD5"); BASE64Encoder encoder = new BASE64Encoder(); //计算字符串的MD5值,然后将MD5值进行Base64编码 String contentMd5 = encoder.encode(messageDigest.digest(exampleString.getBytes("utf-8"))); System.out.println("Content-MD5:" + contentMd5); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { e.printStackTrace(); } } }
  • 功能介绍 OBS的所有API接口都可以通过在header中携带签名方式来进行身份认证,也是最常用的身份认证方式。如图1所示,在Header中携带签名是指将通过HTTP消息中Authorization header头域携带签名信息。 图1 Header中携带签名示例 Authorization header头域的格式为: Authorization: OBS AccessKeyID:Signature Authorization头域的值,由字符串“OBS”、用户访问密钥ID(AK)和签名Signature三部分组成。字符串“OBS”与AK之间用空格分隔,AK与签名之间用英文冒号分隔。 获取访问密钥ID(AK)请参见:管理访问密钥 计算签名Signature的3种方式如表1所示: 表1 计算Header签名的三种方式 计算方式 描述 更多参考 SDK OBS所有语言的SDK都已实现签名,无需手动进行签名计算。推荐您直接使用SDK进行接口调用,更方便快捷。 使用SDK计算签名 可视化签名工具 OBS提供可视化签名计算工具,帮助您轻松完成签名计算。 使用可视化签名工具计算签名 手动编码计算 按照签名算法手动编码计算签名。 手动编码计算签名
  • 使用SDK计算签名 OBS SDK内部已实现签名,因此您在使用SDK访问OBS时,无需关注签名问题。各语言SDK实现签名计算的源码如表2所示: 表2 OBS SDK Header携带签名的实现 SDK 签名实现源文件 Java RestStorageService.java Python auth.py Go auth.go C request.c Node.Js utils.js Browser.Js utils.js PHP DefaultSignature.php .NET Signer.cs
  • 手动编码计算签名 Header中携带签名的计算公式如下: Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) ) OBS API签名的计算过程如下图所示: 图2 计算Header中携带的签名 构造请求字符串(StringToSign)。StringToSign构成和参数说明如下。更多StringToSign构造示例参见StringToSign构造示例。 StringToSign = HTTP-Verb + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedHeaders + "\n" + CanonicalizedResource 表3 构造StringToSign所需参数说明 参数名称 参数类型 是否必选 描述 HTTP-Verb String 必选 参数解释: HTTP方法(也称为操作或动词),对REST接口而言,即为http请求操作的VERB,如:"PUT","GET","DELETE"等字符串,您可根据要调用的API选择。 约束限制: 不涉及 取值范围: GET:请求服务器返回指定资源,如获取桶列表、下载对象等。 PUT:请求服务器更新指定资源,如创建桶、上传对象等。 POST:请求服务器新增资源或执行特殊操作,如初始化上传段任务、合并段等。 DELETE:请求服务器删除指定资源,如删除对象等。 HEAD:请求服务器返回指定资源的概要,如获取对象元数据等。 OPTIONS(暂不支持工具生成签名):请求服务器检查是否具有某个资源的操作权限,需要桶配置CORS。 默认取值: 无,此参数必选。 Content-MD5 String 可选 参数解释: 消息体(body体)的MD5摘要字符串。Content-MD5是按照RFC 1864标准计算出的消息体(body体)的128bit MD5值经过base64编码后得到的字符串。 约束限制: 不涉及 取值范围: 长度为22的字符串。 默认取值: 不设置默认为空。 Content-Type String 可选 参数解释: Content-Type用于指定Object的文件类型,例如: text/plain。文件类型决定浏览器将以什么形式、什么编码读取文件。 约束限制: 不涉及 取值范围: Content-type的取值范围参见如何理解Content-Type(MIME) 默认取值: 当请求中不带该头域时,该参数按照空字符串处理,例如表4。 Date String 必选 参数解释: 请求生成的时间。如果Date与当前服务器的时间相差超过15分钟时,则服务端返回403,认为请求已失效。 约束限制: Date必须为RFC 1123格式的GMT时间。 该值来自于Date头域或者x-obs-date头域。当两头域同时存在时,以x-obs-date为准。 取值范围: 不涉及 默认取值: 不涉及 CanonicalizedHeaders String 可选 参数解释: OBS服务自定义的附加头域,即以“x-obs-”作为前辍的头域,如“x-obs-date,x-obs-acl,x-obs-meta-*”等。每个头域包含头域名称和头域值两部分,如“x-obs-storage-class:STANDARD”中“x-obs-storage-class”是头域名称,“STANDARD”是头域值。 上传对象和上传段支持携带x-obs-content-sha256头域,该头域值为请求消息体(body体)的SHA256值转十六进制值,服务端会对携带此头域的请求计算其消息体的sha256值做校验(性能会有部分下降,在安全上推荐该算法)。 约束限制: 头域名称要转为小写,但头域值要区分大小写,如“x-obs-storage-class:STANDARD”。 头域名称不允许含有非ASCII码或不可识别字符,头域值也不建议使用非ASCII码或不可识别字符。如果一定要使用非ASCII码或不可识别字符,需要客户端自行做编解码处理,可以采用URL编码或者Base64编码,服务端不会做解码处理。 头域中不能含有无意义空格或Tab键时。例如:x-obs-meta-name: name(name前带有一个无意义空格),需要转换为:x-obs-meta-name:name 需要添加多个头域时,所有头域要按照头域名称的字典序从小到大进行排序。 如果头域名称重复,则需要将头域值进行合并,多个头域值以逗号分隔。如:x-obs-meta-name:name1和x-obs-meta-name:name2,合并成x-obs-meta-name:name1,name2。 每一个头域字段都需要另起新行,以换行符“\n”结尾。 取值范围: 调用API时,从API支持的头域中选取。 默认取值: 不设置默认为空。 CanonicalizedResource String 必选 参数解释: HTTP请求所指定的OBS资源,结构如下: CanonicalizedResource = "/" + 桶名 + "/" + 对象名 + "?" + 子资源 以获取对象(GetObject)接口为例,假设桶名为bucket-test,对象名为object-test,对象版本号为xxx,获取时需要重写Content-Type为text/plain,那么CanonicalizedResource为: /bucket-test/object-test?response-content-type=text/plain&versionId=xxx 桶名: 如果桶未绑定自定义域名,则直接使用原始桶名。 如果桶绑定了自定义域名,则桶名由自定义域名表示,如"/obs.ccc.com/object",其中“obs.ccc.com”为桶绑定的自定义域名。 如果API操作不指定桶,例如列举帐号下所有桶操作,则桶名字段和对象名字段都不写。如“/”。 对象名: 要操作对象的对象名。需要遵循对象的命名规则。 子资源(多个子资源需按照字典序从小到大排列,并使用“&”拼接): 资源标识:CDNNotifyConfiguration, acl, append, attname, backtosource, cors, customdomain, delete, deletebucket, directcoldaccess, encryption, inventory, length, lifecycle, location, logging, metadata, modify, name, notification, partNumber, policy, position, quota, rename, replication, restore, storageClass, storagePolicy, storageinfo, tagging, torrent, truncate, uploadId, uploads, versionId, versioning, versions, website,x-obs-security-token, object-lock, retention 用于指定响应头域的子资源:response-cache-control, response-content-disposition, response-content-encoding, response-content-language, response-content-type, response-expires 图片处理相关资源标识: x-image-process, x-image-save-bucket, x-image-save-object 约束限制: 子资源通常是唯一的,不建议包含多个相同关键字的子资源(例如,key=value1&key=value2),如果存在这种情况,OBS服务端签名时只会计算第一个子资源且也只有第一个子资源的值会对实际业务产生作用。 取值范围: 不涉及。 默认取值: 不写默认为“/”。 对第一步的结果进行UTF-8编码。 使用SK对第二步的结果进行HMAC-SHA1签名计算。 对第三步的结果进行Base64编码,得到签名。
  • 功能简介 客户端每次调用OBS API时,都需要在HTTP调用请求中携带签名信息,服务端会对收到的签名信息进行验证。签名验证的目的是: 对请求者进行身份验证,防止未授权用户访问。请求携带的签名包含用户相关信息,华为云会对请求者身份进行验证,只有已授权用户的密钥才能通过签名检查,成功调用API。 防止传输数据被篡改。对数据签名并检验,保障传输内容完整性。 防止签名超期后信息被盗用。设置签名有效期,只有在有效期内签名可以使用,超过有效期后签名失效。
  • 原理说明 OBS签名机制的运作流程如图1所示: 图1 OBS API调用的签名和验签机制 表1 OBS API调用的签名和验签机制 执行端 序号 步骤 说明 客户端 1 构造HTTP请求 用户根据自身诉求构建HTTP请求消息,一个完整的API调用请求包含请求URI、请求方法、请求消息头、请求消息体(可选),如何构造API请求详见构造请求。 2 计算签名S 根据构造的HTTP请求和用户访问密钥计算签名S。您可以根据签名携带方式选择一种签名计算方式: Header携带时如何计算签名? URL携带时如何计算签名? 表单携带时的如何计算签名? 3 将签名S添加到请求消息中 将签名添加到请求消息中,消息携带签名的方式有3种: 添加到HTTP请求的Authorization Header头域 添加到URL的Query参数 POST上传(表单上传)情况下,添加到表单 4 发送携带签名S的API调用请求 将携带签名信息的请求发送给服务端。 OBS服务端 5 接收调用请求 接受客户端的调用请求。 6 验证签名 服务端根据接收到的HTTP请求和用户访问密钥再次计算签名S',比较S'与客户端计算的签名S是否一致,如果一致则签名验证成功,不一致则验证失败。 7 返回API调用结果 如果验证成功则继续执行API,然后向客户端返回API执行结果。 如果验证失败则通知客户端验证失败,状态码为403 Forbidden,错误码为SignatureDoesNotMatch。定位和修复签名不匹配行为请参见签名不匹配(SignatureDoesNotMatch)如何处理 客户端 8 接收服务端响应 客户端接收服务端响应。
  • 携带签名的方式 OBS支持3种携带签名的方式,分别是Header携带、URL携带和表单携带。表单携带签名仅适用于POST上传接口。Header和URL携带签名的区别如下表所示: 表2 OBS API调用携带签名 对比项 Header携带签名 URL携带签名 适用场景 一般情况下,推荐您使用在Header中携带签名。 使用在URL中签名的方式,会将授权的数据在过期时间内暴露在互联网上,具有一定的风险。该方式适用于在不提供给第三方访问密钥的情况下,让第三方能用预签发的URL来进行身份认证,并执行预定义操作。 如何您想通过浏览器访问OBS,建议您使用URL携带签名, 是否支持设置Expires 否 是 是否支持设置Date 是 否 常用API 所有API接口 GET、PUT 时间格式 通过Date头域表示请求生成时间,Date必须为RFC 1123格式的GMT时间。 如果Date与当前服务器的时间相差超过15分钟时,则服务端返回403,认为请求已失效。 Expires字段表示临时授权失效的时间,单位:秒。超过该时间后,URL签名失效。 Signature是否需要URL编码 否 是
  • 请求消息头 可选的附加请求头字段,如指定的URI和HTTP方法所要求的字段。详细的公共请求消息头字段请参见表3。 表3 公共请求消息头 消息头名称 描述 是否必选 Authorization 请求消息中可带的签名信息。 类型:String 默认值:无。 条件:匿名请求不需要带,其他请求必选。 有条件必选 Content-Length RFC 2616中定义的消息(不包含消息头)长度。 类型:String 默认值:无。 条件:PUT操作可选,加载XML的操作必须带。 有条件必选 Content-Type 资源内容的类型,例如: text/plain。 类型:String 默认值:无。 否 Date 请求发起端的日期和时间,例如:Wed, 27 Jun 2018 13:39:15 +0000。 类型:String 默认值:无。 条件:如果是匿名请求或者消息头中带了x-obs-date字段,则可以不带该字段,其他情况下必选。 有条件必选 Host 表明主机地址。如bucketname.obs.cn-north-4.myhuaweicloud.com。 类型:String 默认值:无。 是
  • 请求方法 HTTP方法(也称为操作或动词),它告诉服务你正在请求什么类型的操作。 表2 对象存储支持的REST请求方法 方法 说明 GET 请求服务器返回指定资源,如获取桶列表、下载对象等。 PUT 请求服务器更新指定资源,如创建桶、上传对象等。 POST 请求服务器新增资源或执行特殊操作,如初始化上传段任务、合并段等。 DELETE 请求服务器删除指定资源,如删除对象等。 HEAD 请求服务器返回指定资源的概要,如获取对象元数据等。 OPTIONS 请求服务器检查是否具有某个资源的操作权限,需要桶配置CORS。
  • 发起请求 共有两种方式可以基于已构建好的请求消息发起请求,分别为: cURL cURL是一个命令行工具,用来执行各种URL操作和信息传输。cURL充当的是HTTP客户端,可以发送HTTP请求给服务端,并接收响应消息。cURL适用于接口调试。关于cURL详细信息请参见https://curl.haxx.se/。由于cURL无法计算签名,使用cURL时仅支持访问匿名的公共OBS资源。 编码 通过编码调用接口,组装请求消息,并发送处理请求消息。可以使用SDK或自行编码实现。
共100000条