AWS Developer Blog

Serving Private Content Through Amazon CloudFront Using Signed Cookies

by Milind Gokarn | on | in .NET | Permalink | Comments |  Share

Private content can be served through Amazon CloudFront in two ways: through signed URLs or signed cookies. For information about which approach to choose, see Choosing Between Signed URLs and Signed Cookies.

The AWS SDK for .NET includes an Amazon.CloudFront.AmazonCloudFrontUrlSigner utility class that can be used to generate signed URLs. Based on a customer request, we recently added the Amazon.CloudFront.AmazonCloudFrontCookieSigner utility class to make it easier to generate the cookies required to access private content through Amazon CloudFront.

To start serving private content through Amazon CloudFront:

  • Creating CloudFront Key Pairs for Your Trusted Signers. You can either create a new key pair using the AWS Management Console or, if you have your own RSA key pair, you can upload the public key to create a key pair. Each key pair has a key pair ID, which will be used to create the signed cookies.
  • The RSA key pair file (.pem file) must be available when creating signed cookies. If you created the key pair using the AWS Management Console, you can download the key pair file and store it locally.
  • Adding Trusted Signers to Your Distribution. You can do this through the AWS Management Console or programmatically, through the Amazon.CloudFront.IAmazonCloudFront.CreateDistribution or Amazon.CloudFront.IAmazonCloudFront.UpdateDistribution APIs.

 

Creating Signed Cookies for Canned Policies

Canned policies allow you to specify an expiration date only. Custom policies allow more complex restrictions. For a comparison between the two types of policies, see Choosing Between Canned and Custom Policies for Signed Cookies.

The following code snippet shows the use of the Amazon.CloudFront.AmazonCloudFrontCookieSigner.GetCookiesForCannedPolicy method to create signed cookies for canned policies.

// The key pair Id for the CloudFront key pair
var cloudFrontKeyPairId = "key_pair_id";

// The RSA key pair file (.pem file) that contains the private key    
var privateKeyFile = new FileInfo(@"rsa_file_path"); 

// Path to resource served through a CloudFront distribution
var resourceUri = "http://xyz.cloudfront.net/image1.jpeg" 
    
var cookies = AmazonCloudFrontCookieSigner.GetCookiesForCannedPolicy(
    resourceUri,
    cloudFrontKeyPairId,
    privateKeyFile,
    DateTime.Today.AddYears(1)); // Date until which the signed cookies are valid

Creating Signed Cookies for Custom Policies

You should use custom policies to apply complex restrictions to the accessing of private content. In addition to an expiration date, custom policies allow you to set resource paths with wildcards, activation time, and IP address/address ranges.

The following code snippet shows how to generate signed cookies for custom policies.

// The key pair Id for the CloudFront key pair
var cloudFrontKeyPairId = "key_pair_id"; 

// The RSA key pair file (.pem file) that contains the private key    
var privateKeyFile = new FileInfo(@"rsa_file_path"); 

// Path to resource served through a CloudFront distribution
var resourceUri = "http://xyz.cloudfront.net/image1.jpeg" 

var cookies = AmazonCloudFrontCookieSigner.GetCookiesForCustomPolicy(
    AmazonCloudFrontCookieSigner.Protocols.Http | 
    AmazonCloudFrontCookieSigner.Protocols.Https, // Allow either http or https

    "xyz.cloudfront.net",      // CloudFront distribution domain
    privateKeyFile,
    "content/*.jpeg",          // Allows use of wildcards
    cloudFrontKeyPairId, 
    DateTime.Today.AddDays(1), // Date till which the signed cookies are valid
    DateTime.MinValue,         // Date from which the signed cookies are valid,
	                       // a value of DateTime.MinValue is ignored			
    "192.0.2.0/24");           // Source IP or range of IP addresses,
                               // a value of string.Empty or null is ignored

Send Cookies to a User’s Browser

Typically, you would create signed cookies when a user visits your website and signs in (or meets some other criteria). At that point, the cookies are generated on the web server and included in response. The user’s browser caches these cookies and includes them in subsequent requests to Amazon CloudFront, when the user accesses the URL for private content hosted on Amazon CloudFront.

The following snippet sends the generated cookies back in the HTTP response to the browser in an ASP.NET web application.

using System.Web;
...
// Set signed cookies for precanned policies
Response.Cookies.Add(new HttpCookie(cookies.Expires.Key, cookies.Expires.Value));
Response.Cookies.Add(new HttpCookie(cookies.Signature.Key, cookies.Signature.Value));
Response.Cookies.Add(new HttpCookie(cookies.KeyPairId.Key, cookies.KeyPairId.Value));

//Or set signed cookies for custom policies 
Response.Cookies.Add(new HttpCookie(cookies.Policy.Key, cookies.Policy.Value));
Response.Cookies.Add(new HttpCookie(cookies.Signature.Key, cookies.Signature.Value));
Response.Cookies.Add(new HttpCookie(cookies.KeyPairId.Key, cookies.KeyPairId.Value));

In this blog post, we showed how to use the customer-suggested Amazon.CloudFront.AmazonCloudFrontCookieSigner utility class to generate signed cookies to access private content from Amazon CloudFront. If you have ideas for new utilities or high-level APIs to add to the SDK, please provide your feedback here.