使用 boto3 获取 S3 多区域接入点的预签名 url

问题描述 投票:0回答:1

我在 eu-west-2 有一个 EC2 实例。 我使用 python boto3 生成一个预签名 URL,我将其返回到 Web 浏览器以启用对文件的临时访问,以便可以显示它们。

我在多个区域设置了复制的 S3 存储桶,以及一个多区域访问点。

我用来生成预签名 URL 的代码如下:

s3Config = Config(
    signature_version = 'v4'
)

s3Client_MultiRegion = boto3.client(
    's3',
    aws_access_key_id = appConfig.S3_ACCESS_KEY,
    aws_secret_access_key = appConfig.S3_SECRET_KEY,
    config = s3Config
)

protectedFileUrl = s3Client_MultiRegion.generate_presigned_url(
  HttpMethod='GET',
  ClientMethod="get_object", 
  Params={
    'Bucket': appConfig.AMAZON_S3_BUCKET_MULTIREGIONACCESSPOINT_ARN,
    'Key':folderPath
  },
  ExpiresIn=60
)

当我通过 eu-west-2 外部的 VPN 位置(例如 ap-southeast-1)从 Web 浏览器发出请求时,出现以下错误:

Error parsing the X-Amz-Credential parameter; the region 'us-east-1' is wrong; expecting 'ap-southeast-1'

如果没有指定区域,我假设它默认使用 us-east-1,但我的理解是预签名 URL 应该与位置无关,并且接入点应该路由请求。

如果确实需要指定区域,那么考虑到代码是在 Web 服务器上执行的,我该如何正确执行此操作?

如果不是,我在这里做错了什么?

顺便说一句,我在 cloudfront 发行版后面设置了公共文件,该发行版使用 lambda@edge 函数来修改标头以添加 Sig4 标头。 我假设这对于受保护的文件来说不是必需的,因为预签名 URL 无论如何都应该包含 Sig4 标头。

谢谢你。

amazon-web-services amazon-s3 boto3 pre-signed-url
1个回答
0
投票

您面临的问题是由于签署预签名 URL 时使用的区域与路由请求的区域不匹配所致。即使您使用的是 S3 多区域接入点,预签名 URL 仍然需要包含有效的区域特定签名。

创建预签名 URL 时,它会包含一个区域作为签名的一部分。如果请求最终到达不同的区域(例如在为 us-east-1 签署 URL 时路由到 ap-southeast-1 的示例中),则签名将被拒绝。

您可以使用 Lambda@edge 向标头添加一些属性以进行多区域卸载,或者您可以将region_name 添加到boto3.client s3 配置region_name='eu-west-2',这将起作用好吧,如果您的客户端和服务器通常位于同一区域,或者您可以创建一个函数来根据客户端位置动态处理region_name

def get_region_based_on_client(): 
    ...
    return 'ap-southeast-1'

s3_config = Config(
    signature_version='v4',
    region_name=get_region_based_on_client()
)
© www.soinside.com 2019 - 2024. All rights reserved.