使用带有私钥的云前端生成签名 URL 的问题..使用 Python 3.7 为带有空格的 S3 对象

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

我在使用 Python 3.7 为 S3 对象生成签名 URL 时遇到问题。具体来说,键中带有空格的对象的 URL 会导致“访问被拒绝”错误,而没有空格的对象的 URL 通常工作正常。然而,并非所有没有空格的对象都可以正常工作,并且带有空格的对象始终会失败。

from datetime import datetime ,timedelta
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from botocore.signers import CloudFrontSigner


class SecuringCloudFront:
    def __init__(self):
        pass

    def rsa_signer(self, message):
        try:
            with open('private_key.pem', 'rb') as key_file:
                private_key = serialization.load_pem_private_key(
                    key_file.read(),
                    password=None,
                    backend=default_backend()
                )
            return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())
        except Exception as e:
            print(f"Error loading or signing with private key: {e}")
            return None

    def get_document_images_from_s3(self, images_keys, images_to_get=None):
        """
        Description: creates signed CloudFront URLs for document images

        Author: Safwen Inoubli

        Attributes:
        - images_keys: list of keys
        - images_to_get: list of images index

        Result: list of URLs
        """
        CLOUDFRONT_URL = "https://***********.cloudfront.net"
        KEY_PAIR_ID = "********" #id of stored key 

        images_urls = []
        keys = (
            images_to_get
            if images_to_get is not None
            else list(range(len(images_keys)))
        )
        for key in keys:
            try:
                if key >= len(images_keys) or len(images_keys[key]["name"]) == 0:
                    continue

                s3_key = images_keys[key]["name"]
                url = f"{CLOUDFRONT_URL}/{s3_key}"
                expire_date = datetime.utcnow() + timedelta(hours=24)

                cloudfront_signer = CloudFrontSigner(KEY_PAIR_ID, self.rsa_signer)
                signed_url = cloudfront_signer.generate_presigned_url(
                    url, date_less_than=expire_date
                )
                url = {"url": signed_url} if signed_url else {"url": ""}
            except Exception as e:
                url = {"url": ""}
                print(f"Error generating signed URL: {e}")

            images_urls.append(url)

        return images_urls


if __name__ == "__main__":
    securing_cloud_front = SecuringCloudFront()
    images_keys = [
        {"name": "imageIns3.jpg"}
    ]
    signed_urls = securing_cloud_front.get_document_images_from_s3(images_keys)
    print("Signed URLs:", signed_urls)

用 %20 和 + 替换空格:

我尝试用 URL 中的 %20 和 + 替换对象键中的空格。此方法没有解决问题,我仍然收到“访问被拒绝”错误。 整合自定义政策:

我尝试集成用于签名 URL 生成的自定义策略,但无法理解如何正确应用它。尽管进行了各种尝试,我还是无法使用此方法解决问题。

python amazon-cloudfront pre-signed-url botocore
1个回答
0
投票

其他信息:当尝试直接从 s3 打开无法从 CloudFront 获取有效 URL 的对象时,该对象被归类为“jpg_files”。从 CloudFront 成功检索到的对象被分类为“jpg_images

© www.soinside.com 2019 - 2024. All rights reserved.