在 C# 中使用 AWS Cloudfront API 创建签名 Cookie

Creating Signed Cookies using AWS Cloudfront API in C#

我一直在尝试使用 .NET AWS Cloudfront API 为我的 S3 存储桶创建签名的 cookie,但是每当我发送带有创建的 cookie 的 HTTP 请求时,我只会得到以下结果"Forbidden"。我在这段代码中做错了什么吗?谢谢

CookiesForCannedPolicy cookies = AmazonCloudFrontCookieSigner.GetCookiesForCannedPolicy(
    @"http://distribution123abc.cloudfront.net/*",
    "KEYPAIRID",
    new FileInfo(@"C:\bla\privatekey.pem"),
    DateTime.Now.AddHours(1));

Uri target = new Uri(@"http://distribution123abc.cloudfront.net");
HttpWebRequest pleaseWork = (HttpWebRequest)WebRequest.Create(@"http://distribution123abc.cloudfront.net/files/test.txt");

if (pleaseWork.CookieContainer == null)
{
    pleaseWork.CookieContainer = new CookieContainer();
}
pleaseWork.CookieContainer.Add(new Cookie(cookies.Signature.Key, cookies.Signature.Value) { Domain = target.Host } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.KeyPairId.Key, cookies.KeyPairId.Value) { Domain = target.Host } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.Expires.Key, cookies.Expires.Value) { Domain = target.Host } );

try
{
    WebResponse response = pleaseWork.GetResponse();
    Console.WriteLine("Response content length: " + response.ContentLength);
}
catch(WebException e)
{
    Console.WriteLine(e.Message);
}

我找到了解决办法。我必须改变两件事:

首先,我必须将签名 cookie 用于自定义策略而不是固定策略(因此使用 "Policy" cookie 而不是 "Expires" cookie)。

其次,我为 cookie 设置的域不正确。我需要将域设置为“.cloudfront.net”,而不是为我的分发指定域。

这就是我的代码最终的样子:

CookiesForCustomPolicy cookies = AmazonCloudFrontCookieSigner.GetCookiesForCustomPolicy(
    @"http://distribution123abc.cloudfront.net/*",
    new StreamReader(@"C:\bla\privatekey.pem"),
    "KEYPAIRID",
    DateTime.Now.AddHours(1),
    DateTime.Now.AddHours(-1),
    "1.1.1.1");

string domain = ".cloudfront.net";
HttpWebRequest pleaseWork = (HttpWebRequest)WebRequest.Create(@"http://distribution123abc.cloudfront.net/files/test.txt");

if (pleaseWork.CookieContainer == null)
{
    pleaseWork.CookieContainer = new CookieContainer();
}
pleaseWork.CookieContainer.Add(new Cookie(cookies.Signature.Key, cookies.Signature.Value) { Domain = domain } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.KeyPairId.Key, cookies.KeyPairId.Value) { Domain = domain } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.Policy.Key, cookies.Policy.Value) { Domain = domain } );

try
{
    WebResponse response = pleaseWork.GetResponse();
    Console.WriteLine("Response content length: " + response.ContentLength);
}
catch(WebException e)
{
    Console.WriteLine(e.Message);
}