Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.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
Scala AJAX上传期间Amazon S3签名不匹配_Scala_Amazon S3_Base64 - Fatal编程技术网

Scala AJAX上传期间Amazon S3签名不匹配

Scala AJAX上传期间Amazon S3签名不匹配,scala,amazon-s3,base64,Scala,Amazon S3,Base64,去装配一个AJAX上传到S3,但是请求返回SignatureDesNotMatch。在仔细检查了访问密钥ID和密码之后,我对这个问题感到不知所措。我可以确认我确实也设置了CORS策略文件 以下是AJAX请求: $.ajax({ url: 'https://my-bucket.s3.amazonaws.com/', type: 'POST', contentType: false, da

去装配一个AJAX上传到S3,但是请求返回SignatureDesNotMatch。在仔细检查了访问密钥ID和密码之后,我对这个问题感到不知所措。我可以确认我确实也设置了CORS策略文件

以下是AJAX请求:

$.ajax({
              url: 'https://my-bucket.s3.amazonaws.com/',
              type: 'POST',
              contentType: false,
              data: formData,
              success: function() {
                self.unblockUI($('#body'));
              },
              error: function() {
                self.unblockUI($('#body'));
              },
              cache: false,
              processData: false
            });
在Scala中执行策略编码/签名。代码如下:

  val policy = """
    |{"expiration": "2020-01-01T00:00:00Z",
    |"conditions": [ 
    |{"bucket": "my-bucket"}, 
    |["starts-with", "$key", "uploads/"],
    |{"acl": "public-read"},
    |{"success_action_redirect": "http://example.com/"},
    |["starts-with", "$Content-Type", ""],
    |["starts-with","$Filename",""],
    |["content-length-range", 0, 5242880]
    |]

        |}
        """.stripMargin.stripLineEnd.replaceAll("\n", "").replaceAll("\r","")

  val policyEncoded = (new BASE64Encoder()).encode(policy.getBytes("UTF-8")).stripLineEnd.replaceAll("\n", "").replaceAll("\r","")

  val hmac = Mac.getInstance("HmacSHA1")
  hmac.init(new SecretKeySpec(AWS_SECRET.getBytes("UTF-8"), "HmacSHA1"))

  val policySignature = (new BASE64Encoder()).encode(hmac.doFinal(policy.getBytes("UTF-8"))).stripLineEnd.replaceAll("\n", "").replaceAll("\r","")
正在发送的表格如下:

------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="key"

uploads/reward/img/example_02820838f08sd083k.jpeg
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="AWSAccessKeyId"

<redacted>
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="acl"

public-read
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="success_action_redirect"

http://example.com/
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="policy"

eyJleHBpcmF0aW9uIjogIjIwMjAtMDEtMDFUMDA6MDA6MDBaIiwiY29uZGl0aW9ucyI6IFsgeyJidWNrZXQiOiAicGxhdGZvcm0zLWNsaWVudC1pbWFnZXMifSwgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgInVwbG9hZHMvIl0seyJhY2wiOiAicHVibGljLXJlYWQifSx7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjogImh0dHA6Ly8za3Vkb3MuY29tLyJ9LFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICIiXSxbInN0YXJ0cy13aXRoIiwiJEZpbGVuYW1lIiwiIl0sWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDUyNDI4ODBdXX0gICAg
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="signature"

9jj1hW8pGpS32Ka4KA2R0MwYKTQ=
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="Content-Type"

image/jpeg
------WebKitFormBoundaryTNKMpdRiJxhC39QF
Content-Disposition: form-data; name="file"; filename="youtube_bg.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryTNKMpdRiJxhC39QF--

你知道为什么这会失败吗?我想我已经用尽了所有可能的办法。谢谢

签名有一些问题,但其中之一是我没有正确编码字符串。为了帮助不想使用AmazonSDK的未来Scala用户,这里是我的Scala S3Policy对象,它生成了正确的签名

注意:您不需要使用该游戏!除非您正在使用Play!框架

import play.api.Logger

import sun.misc.BASE64Encoder
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

import com.codahale.jerkson.Json._

object S3Policy {

  val AWS_ACCESS_KEY_ID = "<your access key ID goes here>"
  val AWS_SECRET = "<your secret goes here>"
  val AWS_ALGO = "HmacSHA1"

  val policy = {
    val policyMap = Map(
      "expiration" -> "2014-01-01T12:00:00.000Z'",
      "conditions" -> List(
        Map("bucket" -> "<your bucket goes here>"),
        Map("success_action_status" -> "201"),
        Map("acl" -> "public-read"),
        Array("starts-with", "$key", "uploads/"),
        Array("starts-with", "$Content-Type", ""),
        Array("starts-with", "$x-amz-meta-clientid", ""),
        List("content-length-range", 0, 5242880)
      )
    )
    val generated = generate(policyMap)
    Logger.debug("AWS S3 POLICY: "+generated)
    generated
  }

  val policyEncoded = (new BASE64Encoder()).encode(policy.getBytes("UTF-8")).replaceAll("\n", "").replaceAll("\r","")

  val policySignature = signAndBase64Encode(policyEncoded, AWS_ALGO)

  /**
   * method to sign an AWS request
   */
  def signAndBase64Encode(stringToSign: String, algo: String) = {
    try {
      val mac = Mac.getInstance(algo)
      mac.init(new SecretKeySpec(AWS_SECRET.getBytes("UTF-8"), algo))
      val signature = mac.doFinal(stringToSign.getBytes("UTF-8"))
      val encoded = (new BASE64Encoder()).encode(signature)

      Logger.debug("AWS S3 SIGNATURE: "+encoded)
      encoded

    } catch {
      case e => Logger.error("Unable to calculate a request signature: " + e.getMessage(), e); "ERRORSTRINGNOTCALCULATED"
    }
  }

}

在上面的策略中,您会注意到我使用的是x-amz-meta-field。如果您使用的是S3 metas,则需要以这种或那种方式定义它。

签名有一些问题,但其中之一是我没有正确编码字符串。为了帮助不想使用AmazonSDK的未来Scala用户,这里是我的Scala S3Policy对象,它生成了正确的签名

注意:您不需要使用该游戏!除非您正在使用Play!框架

import play.api.Logger

import sun.misc.BASE64Encoder
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

import com.codahale.jerkson.Json._

object S3Policy {

  val AWS_ACCESS_KEY_ID = "<your access key ID goes here>"
  val AWS_SECRET = "<your secret goes here>"
  val AWS_ALGO = "HmacSHA1"

  val policy = {
    val policyMap = Map(
      "expiration" -> "2014-01-01T12:00:00.000Z'",
      "conditions" -> List(
        Map("bucket" -> "<your bucket goes here>"),
        Map("success_action_status" -> "201"),
        Map("acl" -> "public-read"),
        Array("starts-with", "$key", "uploads/"),
        Array("starts-with", "$Content-Type", ""),
        Array("starts-with", "$x-amz-meta-clientid", ""),
        List("content-length-range", 0, 5242880)
      )
    )
    val generated = generate(policyMap)
    Logger.debug("AWS S3 POLICY: "+generated)
    generated
  }

  val policyEncoded = (new BASE64Encoder()).encode(policy.getBytes("UTF-8")).replaceAll("\n", "").replaceAll("\r","")

  val policySignature = signAndBase64Encode(policyEncoded, AWS_ALGO)

  /**
   * method to sign an AWS request
   */
  def signAndBase64Encode(stringToSign: String, algo: String) = {
    try {
      val mac = Mac.getInstance(algo)
      mac.init(new SecretKeySpec(AWS_SECRET.getBytes("UTF-8"), algo))
      val signature = mac.doFinal(stringToSign.getBytes("UTF-8"))
      val encoded = (new BASE64Encoder()).encode(signature)

      Logger.debug("AWS S3 SIGNATURE: "+encoded)
      encoded

    } catch {
      case e => Logger.error("Unable to calculate a request signature: " + e.getMessage(), e); "ERRORSTRINGNOTCALCULATED"
    }
  }

}
在上面的策略中,您会注意到我使用的是x-amz-meta-field。如果您使用的是S3元,则需要以这种或那种方式定义此方法。

您是否遗漏了该策略对象中的generate方法?generate来自Jerkson:您遗漏了该策略对象中的generate方法?generate来自Jerkson: