Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我必须使用签名v4和假定的角色凭据在JavaScript S3 AWS请求上传递哪些头?_Javascript_Authentication_Amazon Web Services_Amazon S3_Http Headers - Fatal编程技术网

我必须使用签名v4和假定的角色凭据在JavaScript S3 AWS请求上传递哪些头?

我必须使用签名v4和假定的角色凭据在JavaScript S3 AWS请求上传递哪些头?,javascript,authentication,amazon-web-services,amazon-s3,http-headers,Javascript,Authentication,Amazon Web Services,Amazon S3,Http Headers,我正在尝试与AmazonS3建立REST连接,我正在努力实现签名V4过程。我知道,Amazon也提供了JavasScript和sdk,但我需要让它自己工作 为了测试我的代码,我正在使用,并且我的代码成功地返回了预期的结果。然而,我所有的实际尝试都失败了,因为签名不匹配 我的问题是,这些示例不包括任何标题,除了有点简单的host和date之外。我必须通过“完整的monty”,包括访问令牌,并且我确信标题有问题 以下是我在点击按钮时所做的操作: function simpleS3Scenario(m

我正在尝试与AmazonS3建立REST连接,我正在努力实现签名V4过程。我知道,Amazon也提供了JavasScript和sdk,但我需要让它自己工作

为了测试我的代码,我正在使用,并且我的代码成功地返回了预期的结果。然而,我所有的实际尝试都失败了,因为签名不匹配

我的问题是,这些示例不包括任何标题,除了有点简单的
host
date
之外。我必须通过“完整的monty”,包括访问令牌,并且我确信标题有问题

以下是我在点击按钮时所做的操作:

function simpleS3Scenario(my_storage) {
  return new RSVP.Queue()
    .push(function () {
      return my_storage.allDocs();
    })
    .push(function (my_alldocs_response) {
      console.log("initial ALLDOCS")
      console.log(my_alldocs_response);
    })
    ...
};
allDocs
最终将遇到以下情况:

S3Storage.prototype.buildQuery = function (param, options) {
  var context = this,
    url = this._base_url,
    url_path = this._bucket + "/",
    headers,
    requestText;

  return new RSVP.Queue()
    .push(function () {
      return SigV4_custom.makeSignedRequest(
        "GET",
        url + url_path,
        '',
        {"max-key": 100, "prefix": "sample_folder"},
        {},
        context._region,
        "s3",
        "AWS4-HMAC-SHA256",
        context._secret_access_key,
        context._access_key,
        context._session_token
      );
    })
    .push(function (e) {
      console.log("YUPI");
      console.log(e);
    })
    ...   
输入我的请求签名处理程序,该处理程序基于以下代码(不使用签名v4)|代码:

(抱歉,尚未缩短,请向下滚动至入口点,然后开始工作)

var SigV4\u custom=new function(){
this.createCanonicalRequest=函数(){};
this.createStringToSign=函数(){};
this.generateSignatureAndSign=函数(){};
this.makeSignedRequest=函数(){};
}
//修剪多边形填充
String.prototype.trim=String.prototype.trim | |函数(){
var start=-1,
结束=此长度;
而(此charCodeAt(--end)<33);
while(这个.charCodeAt(++start)<33);
返回此.slice(开始、结束+1);
};
//===================发电机功能=================
//为规范请求生成查询参数字符串
函数generateCanonicalQueryString(my_参数_dict){
变量规范查询字符串=“”,
编码的_参数_dict={},
键列表=[],
钥匙
价值
我
伊伦;
//设置和编码
for(输入我的参数){
if(my_参数\u dict.hasOwnProperty(键)){
value=my_参数_dict[key];
如果(值的类型==“对象”){
编码的\参数\ dict[编码元件(键)]=
encodeURIComponent(值[0])+'&';
//将每个附加值附加到查询参数
对于(i=0,i_len=value.length;i  var SigV4_custom = new function(){
    this.createCanonicalRequest = function(){};
    this.createStringToSign = function(){};
    this.generateSignatureAndSign = function(){};
    this.makeSignedRequest = function(){};
  }

  // trim polyfill
  String.prototype.trim = String.prototype.trim || function () {
    var start = -1,
      end   = this.length;

    while( this.charCodeAt(--end) < 33 );
    while( this.charCodeAt(++start) < 33 );

    return this.slice( start, end + 1 );
  };

  // =============== generator funtions =================
  // generate query parameter string for canonical request
  function generateCanonicalQueryString(my_parameter_dict) {
    var canonical_query_string = '', 
      encoded_parameter_dict = {},
      key_list = [],
      key,
      value,
      i,
      i_len;

    // set and encode
    for (key in my_parameter_dict) {
      if (my_parameter_dict.hasOwnProperty(key)) {
        value = my_parameter_dict[key];

        if (typeof value === "object") {
          encoded_parameter_dict[encodeURIComponent(key)] =
            encodeURIComponent(value[0]) + '&';

          // Append each additional value to the query parameter
          for (i = 0, i_len = value.length; i < i_len; i += 1) {
            encoded_parameter_dict[encodeURIComponent(key)] +=
              encodeURIComponent(key) + '=' + encodeURIComponent(value[i]) +'&';
          }
          encoded_parameter_dict[encodeURIComponent(key)] =
            encoded_parameter_dict[encodeURIComponent(key)].slice(0,-1);
        } else {
          encoded_parameter_dict[encodeURIComponent(key)] =
            encodeURIComponent(value);
        }
      }
    }

    // then fill key_list
    for (key in encoded_parameter_dict) {
      if (encoded_parameter_dict.hasOwnProperty(key)) {
        key_list.push(key);
      }
    }

    key_list.sort();
    for (i = 0, i_len = key_list.length; i < i_len; i += 1) {
      canonical_query_string +=
        key_list[i] + "=" + encoded_parameter_dict[key_list[i]] + "&";
    }
    return canonical_query_string.slice(0, -1);
  }

  // generate canonical header string
  function generateCanonicalHeaderString(my_header_dict, is_signature) {
    var canonical_header_string = '',
      encoded_header_dict = {},
      header_list = [],
      header,
      value,
      trimmed_value,
      header_lowercase,
      i,
      i_len,
      separator,
      connector,
      format,
      cutoff;

    if (is_signature) {
      cutoff = -1;
      separator = ":";
      connector = "\n";
      format = function (my_value) {
        return my_value.toLowerCase();
      }
    } else {
      cutoff = -1;
      separator = "=";
      connector = "&";
      format = function (my_value) {
        return my_value;
      }
    }

    // Take header keys and put in array, then sort and build
    for (header in my_header_dict) {
      if (my_header_dict.hasOwnProperty(header)) {
        header_lowercase = format(header);
        value = my_header_dict[header];
        trimmed_value = undefined;

        //XXX there are not only strings in the headers...
        if (value.trim) {
          trimmed_value = value.trim();
        }
        if (encoded_header_dict[header_lowercase] === undefined) {
          encoded_header_dict[header_lowercase] =  trimmed_value || value;
          header_list.push(header_lowercase);
        } else {
          encoded_header_dict[header_lowercase] += "," + trimmed_value || value;
        }
      }
    }
    header_list.sort();
    for (i = 0, i_len = header_list.length; i < i_len; i += 1) {
      canonical_header_string += 
        header_list[i] +
          separator +
            encoded_header_dict[header_list[i]] +
              connector;
    }
    canonical_header_string = canonical_header_string.slice(0, cutoff);
    return canonical_header_string;
  }

  // generate the signed header string
  function generateSignedHeaderString(my_header_dict) {
    var signed_header_string = '', 
      header_list = [],
      header,
      header_lowercase,
      i,
      i_len;

    for (header in my_header_dict) {
      if (my_header_dict.hasOwnProperty(header)) {
        header_list.push(header.toLowerCase());
      }
    }
    header_list.sort();
    for (i = 0, i_len = header_list.length; i < i_len; i += 1) {
      signed_header_string += header_list[i] + ';';
    }

    return signed_header_string.slice(0, -1);
  }

  // returns a timestamp in the YYYYMMDD'T'HHmmSS'Z' format, for SigV4 calls
  function generateTimestamp() {
    var date = new Date();

    function bump(my_time_parameter) {
      if (my_time_parameter.length === 1) {
        return '0' + my_time_parameter;
      }
      return my_time_parameter;
    }

    // Assemble date, bump single digits to doubles
    // validation: return "20130524T000000Z";
    return date.getUTCFullYear() +
      bump((date.getUTCMonth()+1).toString()) + // month
      bump(date.getUTCDate().toString()) + // day
     'T' +
      bump(date.getUTCHours().toString()) + // hour
      bump(date.getUTCMinutes().toString()) + // minute
      bump(date.getUTCSeconds().toString()) + // second
      'Z';
  }

  // generate the credential scope
  function generateCredentialScope(my_timestamp, my_region, my_service) {
    return my_timestamp.substring(0, 8) + "/" + 
      my_region + "/" +
      my_service + "/" +
      "aws4_request";
  }

  // ================== CORE methods ==================
  SigV4_custom.createStringToSign = function (request_time, credential_scope,
    canonical_request, signing_algorithm) {

    // Step 1: designate the algorithm (for SigV4 it is SHA256)
    // Step 2: designate the RequestDate (already done, passed to function)
    // Step 3: create credentialScope (already done, passed to funtion)
    return signing_algorithm + '\n' +
     request_time + '\n' +
     credential_scope + '\n' +
     canonical_request;
  }

  SigV4_custom.generateSignatureAndSign = function(secret, request_time, region,
    service, string_to_sign) {
    var datestamp = request_time.substring(0, 8),
        hash_date,
        hash_region, 
        hash_service,
        hash_signing,
        request = 'aws4_request';

    hash_date = CryptoJS.HmacSHA256(datestamp, 'AWS4' + secret, {asBytes: true});
    hash_region = CryptoJS.HmacSHA256(region, hash_date, {asBytes: true});
    hash_service = CryptoJS.HmacSHA256(service, hash_region, {asBytes: true});
    hash_signing = CryptoJS.HmacSHA256(request, hash_service, {asBytes: true});

    // sign and return
    return CryptoJS.HmacSHA256(string_to_sign, hash_signing)
      .toString(CryptoJS.enc.Hex);
  }

  SigV4_custom.createCanonicalRequest = function(method, pathname,
    parameter_dict, header_dict, hashed_payload) {
    var canonical_request = "",
        http_request_method = "",
        canonical_url = "",
        canonical_query_string = "",
        canonical_header_string = "",
        signed_header_string = "",
        payload;

    // Step 1: Start with the HTTP request method
    http_request_method = method;

    // Step 2: Add the canonicalUrl parameter
    canonical_url = pathname;

    // Step 3: Add the canonicalQueryString parameter
    canonical_query_string = generateCanonicalQueryString(parameter_dict);

    // Step 4: Add the canonicalHeaders parameter
    canonical_header_string = generateCanonicalHeaderString(header_dict, true);

    // Step 5: Add the signedHeaders parameter
    signed_header_string = generateSignedHeaderString(header_dict);

    // Step 6: Add the hashed payload
    payload = hashed_payload;

    // Step 7: string together the canonicalRequest from steps 1 through 6
    canonical_request += http_request_method + '\n' +
      canonical_url + '\n' +
      canonical_query_string + '\n' +
      canonical_header_string + '\n\n' +
      signed_header_string + '\n' +
      payload;

    return canonical_request;
  };

  // =================== ENTRY POINT ===================
  // Call this function to make a SigV4 REST API call. 
  SigV4_custom.makeSignedRequest = function (method, path, payload,
    parameter_dict, header_dict, region, service, signing_algorithm,
    secret_access_key, access_key_id, security_token) {

    var link = document.createElement("a"),
        request_time = generateTimestamp(),
        scope = generateCredentialScope(request_time, region, service),
        authorization_string,
        canonical_request,
        string_to_sign,
        request_uri,
        signature;

    // link is a location object, set its href to use its properties
    link.href = path;

    // set all headers, then generate a canonical_request
    // payload must be hashed here, as this may vary and the hash is required
    // for canonization and as a header. Empty payloads will hash an empty "".
    header_dict['X-Amz-Content-Sha256'] = CryptoJS.SHA256(payload)
      .toString(CryptoJS.enc.Hex);
    header_dict['host'] = link.hostname;
    header_dict['X-Amz-Date'] = request_time;
    header_dict['X-Amz-Credential'] = access_key_id + "/" + scope;
    header_dict['X-Amz-Security-Token'] = security_token;
    header_dict['X-Amz-Algorithm']  = signing_algorithm;
    header_dict['X-Amz-Expires'] = 86400;

    // Task 1: Compute the canonical request
    canonical_request = CryptoJS.SHA256(
      this.createCanonicalRequest(
        method,
        link.pathname,
        parameter_dict,
        header_dict,
        header_dict['X-Amz-Content-Sha256']
      )
    )
    .toString(CryptoJS.enc.Hex);

    // delete host because it is also in the headers (needs to be in both 
    // initially to create the canonicalization)
    delete parameter_dict['host'];

    // Task 2: Create the string to sign using the encoded canonical request
    string_to_sign = this.createStringToSign(
      request_time,
      scope,
      canonical_request,
      signing_algorithm
    );

    // Task 3: Create the signature using the signing key and the string to sign
    signature = this.generateSignatureAndSign(
      secret_access_key,
      request_time,
      region,
      service,
      string_to_sign
    );

    // Task 4: Build the authorization header
    header_dict['Authorization'] = header_dict['X-Amz-Algorithm'] +
      " Credential=" + header_dict['X-Amz-Credential'] + "," +
        "SignedHeaders=" + generateSignedHeaderString(header_dict) + "," +
          "Signature=" + signature;

    // Task 5: Make the request (through jIO)
    return new RSVP.Queue()
      .push(function () {
        return jIO.util.ajax({
          "method": method,
          "url": path,
          "headers": header_dict
        });
      });
  }