我有一些Python,可以请求一个预签名的POST URL将一个对象上传到S3存储桶中。它可以在具有Admin权限的IAM用户下在本地运行它,并且我可以使用Postman和cURL将内容上传到存储桶。但是,当尝试在Lambda中运行相同的代码时,它会显示“您提供的AWS Access Key ID在我们的记录中不存在。”
唯一的区别是Lambda函数在没有管理员权限的情况下运行(但确实具有允许其在存储桶上运行任何S3操作的策略),并且正在使用其他(较旧)的Boto3版本。
我尝试使用从Lambda函数返回的详细信息,与使用本地返回的详细信息完全相同,但是Lambda详细信息不起作用。
答案 0 :(得分:1)
我遇到了同样的问题,这让我发疯了。在本地一切顺利,一旦部署到 lambda 中,我使用 create_presigned_post 或 create_presigned_url 得到 403。
事实证明 lambda 使用的角色与我的本地 aws 用户所拥有的角色不同。 (在我的例子中,lambda 角色是使用 AWS SAM 自动创建的)在授予 lambda 角色 S3 权限后,错误得到解决。
答案 1 :(得分:0)
好问题。您没有描述如何获取Lambda函数的凭据。您的代码,具体是这样:
s3_client = boto3.client('s3')
期望使用〜/ .aws / credentials文件查找默认凭据。您不会(也不应该)在Lambda执行环境中拥有该文件,但是您可能会在本地环境中拥有该文件。我怀疑您根本没有获得Lambda函数的凭据。
在Lambda中有两个选项可用于获取凭据。
答案 2 :(得分:0)
这是100%可行的AWS Lambda解决方案
使用下一个python代码
import uuid
import boto3
def lambda_handler(event, context):
s3 = boto3.client('s3')
upload_key = 'myfile.pdf'
download_key = 'myfile.pdf'
bucket = 'mys3storage'
# Generate the presigned URL for download
presigned_download_url = s3.generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': bucket,
'Key': download_key,
'Expires': 3600
}
)
# Generate the presigned URL for upload
presigned_upload_url = s3.generate_presigned_url(
ClientMethod='put_object',
Params={
'Bucket': bucket,
'Key': upload_key,
'ContentType': 'application/pdf',
'Expires': 3600
}
)
# return the result
return {
"upload_url": presigned_upload_url
"download_url": download_url
}
答案 3 :(得分:0)
当您使用角色时,需要发布x-amz-security-token
值
答案 4 :(得分:0)
您可以尝试下面的代码来生成对象的预签名URL
import json
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client('s3')
bucket = 'test1'
download_key = 'path/to/Object.txt'
def lambda_handler(event, context):
try:
response = s3.generate_presigned_url('get_object',Params={'Bucket': bucket,'Key': download_key},ExpiresIn=3600)
except ClientError as e:
logging.error(e)
return None
url = response
print(url)
return{
'url' : url
}
答案 5 :(得分:0)
Official python tutorial for this 没有在使用 lambda 函数时提及 x-amz-security-token
,但是在将文件上传到 S3 时需要将其作为表单值包含在内。所以总结一下,在使用 lambda 时,请确保附加到函数的角色具有 s3 访问权限,并且额外的表单字段存在 x-amz-security-token
值。
<form action="URL HERE" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="KEY HERE" />
<input type="hidden" name="AWSAccessKeyId" value="ACCESS KEY HERE" />
<!-- ADD THIS ONE -->
<input type="hidden" name="x-amz-security-token" value="SECURITY TOKEN HERE" />
<!-- ADD THIS ONE -->
<input type="hidden" name="policy" value="POLICY HERE" />
<input type="hidden" name="signature" value="SIGNATURE HERE" />
File:
<input type="file" name="file" /> <br />
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>