简体   繁体   中英

How to Generate SignedUrls for CloudFront in Lambda Using Python?

I'm currently having an issue with my python code, this code generates a Cloud Front signed URL and prints it. I have a virtual environment in VS Code and it works fine but as soon as I upload it to lambda I get the error: "errorMessage": "No module named '_cffi_backend""

I have tried:

pip install -t $PWD cffi

pip install -t $PWD cryptography

zipping them into a.zip file and uploading it to lambda to meet the requirements, and I've also zipped all the packages within my virtual environment that has working dependencies.

How can I resolve this issue? I need this to be in lambda, and I've reinstalled cffi before aswell.

import datetime

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from botocore.signers import CloudFrontSigner


def rsa_signer(message):
    with open('key.pem', 'rb') as key_file:
        private_key = serialization.load_pem_private_key(
            key_file.read(),
            password=None,
            backend=default_backend()
        )
        print (message)
    return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())

def lambda_handler(event, context):

    key_id = 'APKAJSKEXampleKNQ'
    url = 'https://example.com/example.html'
    expire_date = datetime.datetime(2021, 1, 1)

    cloudfront_signer = CloudFrontSigner(key_id, rsa_signer)

    # Create a signed url that will be valid until the specfic expiry date
    # provided using a canned policy.
    signed_url = cloudfront_signer.generate_presigned_url(
        url, date_less_than=expire_date)
    print(signed_url)

{
  "errorMessage": "No module named '_cffi_backend'",
  "errorType": "ModuleNotFoundError",
  "stackTrace": [
    "  File \"/var/task/why.py\", line 31, in lambda_handler\n    url, date_less_than=expire_date)\n",
    "  File \"/var/runtime/botocore/signers.py\", line 344, in generate_presigned_url\n    signature = self.rsa_signer(policy)\n",
    "  File \"/var/task/why.py\", line 15, in rsa_signer\n    backend=default_backend()\n",
    "  File \"/var/task/cryptography/hazmat/backends/__init__.py\", line 15, in default_backend\n    from cryptography.hazmat.backends.openssl.backend import backend\n",
    "  File \"/var/task/cryptography/hazmat/backends/openssl/__init__.py\", line 7, in <module>\n    from cryptography.hazmat.backends.openssl.backend import backend\n",
    "  File \"/var/task/cryptography/hazmat/backends/openssl/backend.py\", line 109, in <module>\n    from cryptography.hazmat.bindings.openssl import binding\n",
    "  File \"/var/task/cryptography/hazmat/bindings/openssl/binding.py\", line 14, in <module>\n    from cryptography.hazmat.bindings._openssl import ffi, lib\n"
  ]
}

I read the source code for the "boto" Cloud Front Signer and found that all functions are built-in. There's no need to use "cryptography.hazmat".

I switched the above code to something a bit more simple.

from boto.cloudfront.distribution import Distribution
from boto.cloudfront import CloudFrontConnection
from botocore.signers import CloudFrontSigner
import datetime
import rsa

def rsa_signer(message):
    private_key = open('key.pem', 'r').read()
    return rsa.sign(message, rsa.PrivateKey.load_pkcs1(private_key.encode('utf8')),'SHA-1')

def lambda_handler(event, context):
    url = "https://Example.com/Register.html"                                                                                                                                                                      
    expire_date = datetime.datetime(2021, 1, 1)
    key_id = 'APKAJSEXAMPLENXQ'
    cf_signer = CloudFrontSigner(key_id, rsa_signer)
    signed_url = cf_signer.generate_presigned_url(url, date_less_than=expire_date)
    print(signed_url)

For anyone wondering this is how to properly generate a Cloud Front PresignedUrl using python. Make sure to package "boto" and "rsa" into your zip file when uploading to lambda.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM