我有一个lambda函数,它从S3事件中获取S3对象并使用自定义元数据更新它。
下面是boto3脚本:
import json
import boto3
s3 = boto3.resource('s3')
def lambda_handler(event, context):
key = event['Records'][0]['s3']['object']['key']
key_name = key.split('/')
bucket = event['Records'][0]['s3']['bucket']['name']
print(key)
print(bucket)
s3_object = s3.Object(bucket, key)
s3_object.metadata.update({'Cache-Control':'no-cache'})
s3_object.copy_from(CopySource={'Bucket':bucket, 'Key':key}, Metadata=s3_object.metadata, MetadataDirective='REPLACE')
当我运行这个脚本时,它会给出以下错误:
调用CopyObject操作时发生错误(SignatureDoesNotMatch):我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法.:ClientError
(注:我已对lambda函数角色给予了足够的许可)
我需要在这里签名吗?
发布于 2020-11-24 23:47:32
对象的键中可能含有一些奇怪的字符。
下面是一些对我有用的稍微修改过的代码:
import boto3
import urllib
s3 = boto3.resource('s3')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])
s3_object = s3.Object(bucket, key)
s3_object.metadata.update({'Cache-Control':'no-cache'})
s3_object.copy_from(CopySource={'Bucket':bucket, 'Key':key}, Metadata=s3_object.metadata, MetadataDirective='REPLACE')
发布于 2022-05-20 12:31:25
约翰·罗滕斯坦的答案行得通,但只有一次。运行相同的脚本两次会复制错误操作。
我相信这与原因有关:
用户定义的元数据是一组键值对.亚马逊S3以小写形式存储用户定义的元数据键。
https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingMetadata.html
注意,虽然Amazon将键存储为小写,但OP使用的是大写。将“缓存控制”更改为小写的“缓存控制”将允许您更新“缓存控制”已经是元数据条目的对象上的元数据。
我已经测试了区分大小写的问题,并且能够在不使用键大写的情况下工作,并在密钥大写重新引入时重现问题。
在客户端和AWS的API后端上如何计算签名似乎存在差异。大写问题仅在元数据项在对象上预先存在时才表示出来。这可能需要使用AWS引发有关boto3库的票证。
https://stackoverflow.com/questions/64998595
复制