Search code examples
c#amazon-web-servicescookiesamazon-s3amazon-cloudfront

Creating Signed Cookies using AWS Cloudfront API in C#


I have been trying to use the .NET AWS Cloudfront API to create signed cookies for my S3 bucket, but whenever I send an HTTP request with the cookies that are created, I just get a result of "Forbidden". Is there something I am doing wrong in this code? Thanks.

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

Solution

  • I found a solution. I had to change two things:

    First I had to use signed cookies for a custom policy rather than a canned policy (and therefore use a "Policy" cookie rather than an "Expires" cookie).

    Second, the domain I was setting for my cookies was incorrect. I needed to set the domain as just ".cloudfront.net", rather than specifying the domain for my distribution.

    This is what my code looked like in the end:

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