s3 SignedUrl x-amz-security-token

时间:2018-10-19 03:15:00

标签: amazon-web-services amazon-s3

const AWS = require('aws-sdk');

export function main (event, context, callback) {
  const s3 = new AWS.S3();
  const data = JSON.parse(event.body);`

  const s3Params = {
    Bucket: process.env.mediaFilesBucket,
    Key: data.name,
    ContentType: data.type,
    ACL: 'public-read',
  };

  const uploadURL = s3.getSignedUrl('putObject', s3Params);

  callback(null, {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*'
    },
    body: JSON.stringify({ uploadURL: uploadURL }),
  })
}

当我在本地对其进行测试时,它可以很好地工作,但是在部署它后,它会发出x-amz-security-token令牌,然后出现拒绝访问的响应。如何摆脱这个x-amz-security-token?

3 个答案:

答案 0 :(得分:1)

我刚刚解决了一个非常相似的问题,可能与您遇到的问题相同。我说这可能是因为您没有说要进行什么部署。我假设您正在部署到Lambda,但可能并不适用,这可能适用或可能不适用,但是如果您使用的是临时凭据,则将适用。

我最初使用的是您上面使用的方法,但是后来使用了npm模块aws-signature-v4来查看它是否不同并得到与您相同的错误。

您将需要令牌,当您使用临时凭据签署请求时就需要令牌。在Lambda的情况下,凭据位于运行时中,包括您需要传递的会话令牌,其他地方也很可能同样如此,但是我不确定几年内没有使用过ec2。

埋在文档中(很抱歉,我找不到在此声明的地方),指出某些服务要求session_token与其他规范查询参数一起处理。正如sig v4指令所暗示的那样,我正在使用的模块最后添加了它,因此我对其进行了修改,使令牌具有规范性并可以正常工作。

我们已经更新了aws-signature-v4模块的实时版本以反映此更改,现在它可以很好地用于签署s3请求。

Signing is discussed here

我会使用我做过的模块,因为我感觉到sdk出于某种原因做错了事。

使用示例(此文件包装在multiPart上传文件中,因此包含零件编号和上传ID):

function createBaseUrl( bucketName, uploadId, partNumber, objectKey ) {
  let url = sig4.createPresignedS3URL( objectKey, {
    method: "PUT",
    bucket: bucketName,
    expires: 21600,
    query: `partNumber=${partNumber}&uploadId=${uploadId}`
  });
  return url;
}

答案 1 :(得分:0)

我遇到了同样的问题。使用serverless-offline一切都可以正常工作,但是当我部署到Lambda时,我开始在URL上收到AccessDenied问题。比较serverless-offline与AWS部署之间返回的URL时,我注意到唯一的区别是URL中包含了X-Amz-Security-Token作为查询字符串参数。经过一番挖掘后,我发现分配的令牌是基于lambda函数具有的假定角色。我要做的就是为该角色授予适当的S3策略,并且该策略有效。

答案 2 :(得分:0)

我遇到了同样的问题,我正在使用Python3.7中的库Boto3创建一个签名的URL

尽管这不是建议的解决方法,但它对我有用。

请求方法应为POST,content-type = ['multipart / form-data']

以这种方式创建客户端。

# Do not hard code credentials
client = boto3.client(
    's3',
    # Hard coded strings as credentials, not recommended.
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_ACCESS_KEY'
)

返回响应

bucket_name = BUCKET
acl = {'acl': 'public-read-write'}
file_path = str(file_name) //file you want to upload
response = s3_client.generate_presigned_post(bucket_name,
                                                 file_path,
                                                 Fields={"Content-Type": ""},
                                                 Conditions=[acl,
                                                    {"Content-Type": ""},
                                                    ["starts-with", "$success_action_status", ""],
                                                 ],
                                                 ExpiresIn=3600)