1

我正在尝试为我的 s3 存储桶创建签名的 url,只有选定的人才能访问,直到时间到期。

我无法在我的代码中找到问题。请帮忙

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))

当我在 lambda 上测试文件时,我能够生成并打印一个 URL,但是当我访问该 URL 时,我收到来自 XML 文件的拒绝访问错误消息。

我不确定我在这一点上做错了什么。为了测试我是否能够生成任何 SignedUrl,我创建了一个 node.js lambda,我可以在其中成功生成 URL 甚至访问我的页面。

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

1 回答 1

1

在多次尝试使我的代码工作失败后,我决定采用不同的方法并使用 node.js 来满足我的需求。下面的代码完美运行,我能够生成签名的 url

现在我使用硬编码的时间值来测试我的代码,稍后将使用 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);
  
};
于 2020-07-22T15:34:29.047 回答