【问题标题】:s3 presigned url mandatory custom request headerss3 presigned url 强制自定义请求标头
【发布时间】:2019-02-06 09:15:31
【问题描述】:

我正在尝试生成一个带有一些用户数据的预签名 url, 据我了解,我需要使用自定义请求标头

GeneratePresignedUrlRequest generatePresignedUrlRequest =
    new GeneratePresignedUrlRequest(bucket, objectKey)
        .withMethod(httpMethod)
        .withExpiration(expiration);
if (params != null) {
  params.forEach(
      (k, v) ->
          generatePresignedUrlRequest.putCustomRequestHeader(
              Headers.S3_USER_METADATA_PREFIX + k.toLowerCase(), v));
}
return s3.generatePresignedUrl(generatePresignedUrlRequest);

即使生成的 url 的消费者需要设置标题。 有什么办法可以强制消费者添加这些标题? 例如:当所需的标头(自定义)不存在时抛出错误请求(400)

【问题讨论】:

    标签: java amazon-s3 pre-signed-url custom-headers


    【解决方案1】:

    你看过addRequestParameter吗?这将添加查询字符串参数,如果没有这些参数,请求将失败。

    例如

    generatePresignedUrlRequest.addRequestParameter(Headers.S3_USER_METADATA_PREFIX + "test", "true");
    

    生成的 url 将包含以下参数:

    https://aws-domain/file.ext?x-amz-meta-test=true&X-Amz-Security-Token=<TOKEN>
    

    更新:

    我一直在 Node.js 中使用 getSignedUrl API 在查询字符串参数中生成带有用户元数据的签名 url。我不是 JAVA 开发人员,这就是为什么我建议您使用 addRequestParameter,它似乎会生成带有方法中提供的元数据的签名 url。

    Node.js 代码

    const url = s3.getSignedUrl('putObject', {
      'Bucket': 'my-bucket',
      'Key': 'signed.json',
      'Metadata': {
        'my-id': '1234'
      }
    });
    

    签名网址

    https://my-bucket.s3.eu-west-1.amazonaws.com/signed.json?AWSAccessKeyId=<AccessKey>&Expires=1549497606&Signature=<SignatureKey>&x-amz-meta-my-id=1234
    

    上传文件

    curl -k -X PUT -T "signed.json" "https://my-bucket.s3.eu-west-1.amazonaws.com/signed.json?AWSAccessKeyId=<AccessKey>&Expires=1549497606&Signature=<SignatureKey>&x-amz-meta-my-id=1234"
    

    用户元数据

    客户端无需添加任何标头即可添加用户元数据。如果客户端尝试修改 x-amz-meta-* 或删除它,他们将得到 SignatureDoesNotMatch 这正是您想要的。

    修改 x-amz-meta-my-id

    curl -k -X PUT -T "signed.json" "https://my-bucket.s3.eu-west-1.amazonaws.com/signed.json?AWSAccessKeyId=<AccessKey>&Expires=1549497606&Signature=<SignatureKey>&x-amz-meta-my-id=123"
    

    预期错误:

    <?xml version="1.0" encoding="UTF-8"?>
    <Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAJ5PO6T7F772ZPSPQ</AWSAccessKeyId>
    

    【讨论】:

    • url 将包含这些元数据,但是如何在另一端访问这些数据? S3Object 用户数据不使用此 RequestParameters 填充,仅使用标题对吗?
    • 您不需要访问您已经指定在使用 URL 时需要该元数据的数据。因此,如果客户端尝试删除添加的参数之一,则请求将失败。是的,它会添加元数据。
    • x-amz-meta-test=true 以后如何访问这些数据?基本上我正在添加额外的信息,如果它没有被存储那么就没有用了吗?参考forums.aws.amazon.com/thread.jspa?threadID=297677
    • @A.Khan 我不知道x-amz-meta-* 实际上是由PUT 对象API 从查询字符串中处理的。这不是记录的行为——这些应该是请求标头,而不是查询字符串参数。我很想知道这是否真的有预期的效果,或者它是否只是成为一种防篡改的无操作。
    • @Michael-sqlbot 我知道它可以工作,因为我目前在我的一个项目中使用 AWS JS SDK。正如您所说,这不是记录在案的行为,至少我找不到。因为我不是 JAVA 开发人员,这就是为什么我要求 OP 使用 addRequestParameter 进行测试的原因,它似乎添加了查询字符串参数并生成与我期望从 js sdk 相同的 URL。我将更新我的答案以放置我的 Node.js 代码。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2014-08-08
    • 2016-06-24
    • 2013-11-13
    • 2014-08-13
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多