Access Denied Signed URL Python3 using cloud front

260 views Asked by At

I am trying to create signed urls for my s3 bucket to which only select people will have access to until the time expires.

I am not able to find the issue in my code. Please help

import boto
from boto.cloudfront import CloudFrontConnection
from boto.cloudfront.distribution import Distribution
import base64
import json 
import rsa
import time                                                                                                                                                              

def lambda_handler(event, context):
    
    url = "https://notYourUrl.com/example.html"                                                                                                                                                                      
    expires = int(time.time() + 36000)
    
    pem = """-----BEGIN RSA PRIVATE KEY-----
               myKey
    -----END RSA PRIVATE KEY-----"""

Cloudfront console
    key_pair_id = 'myKey'    
    
    policy = {
        "Statement": [
            {
                "Resource":url,
                "Condition":{
                    "DateLessThan":{"AWS:EpochTime":expires},
                }
            }
        ]
    }
    
    policy = json.dumps(policy)
    private_key = rsa.PrivateKey.load_pkcs1(pem)
    
    policy = policy.encode("utf-8")
    signed = rsa.sign(policy, private_key, 'SHA-1')
    policy = base64.b64encode(policy)
    policy = policy.decode("utf-8")
    signature = base64.urlsafe_b64encode(signed)
    signature = signature.decode("utf-8")
    
    policy = policy.replace("+", "-")
    policy = policy.replace("=", "_")
    policy = policy.replace("/", "~")
    
    signature = signature.replace("+", "-")
    signature = signature.replace("=", "_")
    signature = signature.replace("/", "~")

    print("%s?Expires=%s&Signature=%s&Key-Pair-Id=%s" % (url,expires, signature, key_pair_id))

When I test the file on lambda I am able to produce and print a URL but when I access the URL I receive an access denied error message from the XML file.

I am not sure what I am doing wrong at this point. To test if I am able to generated any SignedUrl I created a node.js lambda in which I am successfully able to generate the URL and even access my page.

<Error>
<Code>AccessDenied</Code>
<Message>Access denied</Message>
</Error>
1

There are 1 answers

0
flyiinhigh On BEST ANSWER

After many failed tries to make my code work I decided to go with a different approach and used node.js to fullfill my needs. The code below works perfectly and I am able to generate signed url's

For now I used a hardcoded time value to test my code and will later on work on getting that dynamically using datetime.

var AWS = require('aws-sdk');
var keyPairId = 'myKeyPairId';
var privateKey = '-----BEGIN RSA PRIVATE KEY-----' + '\n' +

    '-----END RSA PRIVATE KEY-----';
var signer = new AWS.CloudFront.Signer(keyPairId, privateKey);

exports.handler = function(event, context) {
    var options = {url: "https://notYourUrl.com/example.html", expires: 1621987200, 'Content-Type': 'text/html'};
    //console.log(options);
    const cookies = signer.getSignedCookie(options);
    const url = signer.getSignedUrl(options);
    
    console.log("Printing URL "+url);
    console.log(cookies);
  
};