zoukankan      html  css  js  c++  java
  • s3接口认证说明

    S3 Authorization太绕,太头痛,下面解释说明:

    XS3 REST API基于HMAC(哈希消息身份验证码)密钥使用自定义HTTP方案进行身份验证。要对请求进行身份验证,您首先需要合并请求的选定元素以形成一个字符串。然后,您可以使用XS3私

    有访问密钥来计算该字符串的HMAC。通常我们将此过程称为“签署请求”并且我们将输出HMAC算法称为“签名”,因为它会模拟真实签名的安全属性。最后,您可以使用本部分中介绍的语法,作为请求的参数添加此签名。

    系统收到经身份验证的请求时,将提取您申领的XS3私有访问密钥,并以相同的使用方式将它用于计算已收到的消息的签名。然后,它会将计算出的签名与请求者提供的签名进行对比。如果两个签名相匹配,则系统认为请求者必须拥有对XS3私有访问密钥的访问权限,因此充当向其颁发密钥的委托人的颁发机构。如果两个签名不匹配,那么请求将被丢弃,同时系统将返回错误消息。

    身份验证标头
    XS3 REST API使用标准的 HTTP Authorization标头来传递身份验证信息。(标准标头的名称是不可取的,因为它承载的是身份验证信息,而不是授权。)在XS3身份验证方案下,授权标头具有以下形式:
    Authorization: AWS Access Key: Signature

    新用户注册后,会向开发人员颁发访问密钥 ID和私有访问密钥。对于请求身份验证,Access Key元素将标识用于计算签名的访问密钥 ID和进行请求的开发人员(间接)。

    Signature元素是请求中选定元素的 RFC 2104 HMAC-SHA1,因此授权标头的Signature部分会因请求的不同而异。如果系统计算出的请求签名与请求随附的Signature相匹配,则请求者证明拥有XS3私有访问密钥。然后在该身份下,借助获得此密钥的开发人员的授权来处理请求。

    用于签名的请求规范

    在系统收到经身份验证的请求时撤销,系统会将计算出的请求签名与StringToSign中提供的签名进行对比。基于此原因,您必须采用XS3使用的相同方法计算签名。根据适用于签名的统一格式放置请求的过程称为标准化。

    Authorization字段计算方法如下:

    在该示例中,“ ” 表示Unicode码位 U+000A,这通常称为换行符。

    "Authorization: AWS " + Access Key + ":" + Signature

    Signature = Base64(HMAC-SHA1( Secret Key, UTF-8-Encoding-Of( StringToSign )))

    StringToSign =VERB + " "

    + CONTENT-MD5 + " "

    + CONTENT-TYPE + " "

    + DATE + " "

    + CanonicalizedHeaders

    + CanonicalizedResource))

    - Access Key:XS3提供
    - Signature:HMAC-SHA1 是由RFC 2104(用于消息身份验证的哈希密钥)定义的算法。该算法要求输入两个字节字符串:一个密钥和一个消息。对于XS3请求身份验证,请将您的私有访问密钥(Secret Key) 用作密钥,并将UTF-8编码格式的StringToSign用作消息。HMAC-SHA1的输出也是字节字符串,称为摘要。通过对此摘要进行Base64编码来构成Signature请求参数。
    - VERB:HTTP协议请求,如GET/PUT/DELETE等。
    - CONTENT-MD5:标准 HTTP 请求的CONTENT-MD5,计算方法参见 RFC1864
    - CONTENT-TYPE:表示请求内容的类型,例如“application/xml”

    如果请求中没有CONTENT-MD5或者CONTENT-TYPE头信息(例如,Content-Type或Content-MD5对于PUT请求是可选的,并且对于GET请求没有任何意义),请使用空字符串 ("") 替换该位置。

    -          DATE表示此次操作的时间,且必须为 HTTP1.1中支持的GMT格式

    某些 HTTP 客户端库不提供为请求设置Date标头的功能。如果您在标准化标头中包含“Date”标头的值时遇到困难,您可以改用“x-amz-date”标头为请求设置时间。x-amz-date标头的值必须采用 RFC 2616格式 (http://www.ietf.org/rfc/rfc2616.txt) 之一。 x-amz-date标头位于请求中时,系统将在计算请求签名时忽略任何Date标头。因此,如果包含了x-amz-date标头,请在构建Date时使用StringToSign的空字符串。

    构建CanonicalizedHeaders元素

    所有以“x-amz-”为前缀的HTTP Header被称为CanonicalizedHeaders。

    它的构建方法如下:

    1) 将所有以“x-amz-”为前缀的HTTP请求头的名字转换成小写字母。如‘X-AMZ-Meta-Name: Hello’

    转换成‘x-amz-meta-name: hello’。

    2) 将上一步得到的所有HTTP 请求头按照字典序进行升序排列。

    3) 如果有相同名字的请求头,则根据标准RFC 2616, 4.2 章进行合并(两个值之间只用逗号分隔)。

    如有两个名为‘x-amz-meta-name’的请求头,对应的值分别为‘hello’和‘world,则合并后

    为:‘x-amz-meta-name:hello,world。

    4) 通过将折叠空格(包括换行符)替换为单个空格,“展开”跨多个行的长标头.

    5) 删除请求头和内容之间分隔符两端出现的任何空格。如‘x-amz-meta-name: hello,world转换

    成:‘x-amz-meta-name:hello,world。

    6) 最后,请向生成的列表中的每个标准化标头附加换行字符 (U+000A)。通过将此列表中所有的标头

    规范化为单个字符串,构建 CanonicalizedResource 元素。

    构建CanonicalizedResource元素
    用户发送请求中想访问的XS3目标资源被称为 CanonicalizedResource。

    它的构建方法如下:
    1) 将CanonicalizedResource 置成空字符串(“”)
    2) 附加未解码的HTTP请求-URI 的路径部分(取决于但不包括查询字符串):“/BucketName/ObjectName”(无ObjectName则不填;如果ObjectName为中文,请用UTF-8编码)。
    对于不寻址bucket的请求(例如,GET Service),请附加“/”。
    3) 如果请求将寻址子资源,请附加子资源、其值(如果有)和问号。请注意,如果存在多个子资源,子资源必须按子资源名称的字典顺序排序并使用“&”进行分隔。此时的CanonicalizedResource例子如:/BucketName/ObjectName?acl &uploadId=UploadId
    构建CanonicalizedResource元素时如果有以下子资源,则必须包含他们:acl、partNumber、uploadId和uploads。

    python示例代码

    import urllib2
    import hashlib
    import datetime
    import base64
    import exceptions
    import hmac
    GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
    MyAccessKey='QYV025X8CC65JOUAZ2KO'
    MySecretKey='V+g3qxqlCfT28kIUjllYqaDpKwYEqNAFAJ2ijlwN'
    myDate= datetime.datetime.utcnow().strftime(GMT_FORMAT)
    def authStr():
    mystr="GET
    
    
    "+myDate+"
    /"
    myhmac= hmac.new(MySecretKey,digestmod=hashlib.sha1)
    myhmac.update(mystr)
    signStr=base64.encodestring( myhmac.digest())
    result= "AWS %s:%s" %(MyAccessKey,signStr)
    return result.strip()
    def start():
    
    req=urllib2.Request('http://xxxxx:80')
    req.add_header('Date',myDate)
    req.add_header('AWSAccessKeyId',MyAccessKey)
    req.add_header('Authorization',authStr())
    print req.headers
    response=urllib2.urlopen(req)
    print response.read()
    if __name__ =="__main__":
    start()

    参考文档:http://docs.ceph.com/docs/master/radosgw/s3/authentication/

  • 相关阅读:
    ES6标准入门 第一章:简介
    vue调试工具之 vue-devtools的安装
    vue 高德地图之玩转周边
    vue-动手做个选择城市
    js 高级算法
    (转)预处器的对比——Sass、LESS和Stylus
    windows下安装mongodb以及node.js连接mongodb
    vue组件(将页面公用的头部组件化)
    浅谈移动端rem的用法
    vue 调用高德地图
  • 原文地址:https://www.cnblogs.com/landhu/p/5889547.html
Copyright © 2011-2022 走看看