Amazon CloudFront
Developer Guide (API Version 2012-07-01)
« PreviousNext »
View the PDF for this guide.Go to the AWS Discussion Forum for this product.Go to the Kindle Store to download this guide in Kindle format.Did this page help you?  Yes | No |  Tell us about it...

Authenticating REST Requests

Every request you make to the CloudFront API must be authenticated. AWS and others in the coding community provide tools that automatically sign your requests as required for CloudFront. For more information, see Where Do I Go from Here? and the CloudFront sample code and libraries page. If you plan to write your own code to sign requests, then read this topic.

Comparison with Amazon S3

If you already know how authentication works for Amazon S3 REST requests, then the information in this topic will be familiar to you. Here are the main differences between how you authenticate CloudFront and Amazon S3 requests:

  • For CloudFront, you must use HTTPS

  • For CloudFront, the canonical string to sign is simply the value of the Date header (or the x-amz-date header if you include it in the request)

    Therefore, the value of the Authorization header is as follows:

    Authorization: "AWS" + " " + AWSAccessKeyID + ":" + 
                    Base64(HMAC-SHA1(UTF-8(Date), UTF-8(AWSSecretAccessKey)))

Overview of the Authentication Process

Authentication is how you prove your identity to the system. You must prove your identity in all your requests to the CloudFront API. The following sections describe how.

The CloudFront REST API uses a custom HTTP scheme based on a keyed-HMAC (Hash Message Authentication Code) for authentication. The following task list describes the basic process for authentication.

Process for Request Authentication

  1. You create a string based on specific information in the request. For more information, see The String to Sign.

  2. You calculate a signature using your AWS Secret Access Key, the string from task 1, and an HMAC-SHA1 algorithm.

    Informally, we call this process signing the request, and we call the output of the HMAC algorithm the signature because it simulates the security properties of a real signature. For instructions on creating the signature, see Calculating the Signature.

  3. You include the signature in the request and send the request to AWS using HTTPS (HTTP requests are not accepted).

    For information about where to put the signature in the request, see The Authorization Header.

  4. We check your signature.

    When we receive your request, we fetch the AWS Secret Access Key that you claim to have and use it in the same way you did to compute a signature for the message. We then compare the signature we calculated to the signature you presented in the request. If the two signatures match, we accept and process the request. Otherwise, we reject the request and respond with an error message. For more information, see Authentication Errors.

Note

We also confirm the request time stamp is within 15 minutes of the AWS server time. For more information, see Fetching the Date.

The String to Sign

In the first task in the preceding process, you form a string. The string is simply the UTF-8 encoded value of the Date header in the request (e.g., Thu, 17 May 2012 19:37:58 GMT). Your request must include either the Date header, the x-amz-date header, or both (if both are present, we ignore the Date header when authenticating the request). You might decide to include the x-amz-date header if your HTTP client doesn't let you set the Date header.

The format you use for the header value must be one of the full date formats specified in RFC 2616, section 3.3.1, for example, Wed, 05 Apr 2006 21:12:00 GMT. For more information, go to the RFC 2616 specification.

Calculating the Signature

Calculating the value to include in the request is a simple procedure.

Calculating the Signature

  1. Calculate an RFC 2104-compliant HMAC-SHA1 hash, using the string (see The String to Sign) and your Secret Access Key as the key.

  2. Convert the resulting value to base64.

    The result is the signature you include in the request.

The following example shows a string, a fake Secret Access Key, and an example of a Base64-encoded signature. Note that the credentials have been obfuscated, so calculating using these values does not produce the Base64-encoded signature listed in the table.

  • String: Thu, 17 May 2012 17:08:48 GMT

  • Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

  • Base64-encoded signature: 4cP3hCesdCQJ1jP11111YSu0g=EXAMPLE

The Authorization Header

To pass the signature to AWS, you include it as part of the standard HTTP Authorization header. You include both the signature and your AWS Access Key ID in the header using the following format:

Authorization: AWS <AWSAccessKeyId>:<Signature>

Note that there is a space after AWS.

Following is an example REST request with the example signature calculated in the preceding section. The AWS Access Key ID (AKIAIOSFODNN7EXAMPLE) is fake.

POST /2012-07-01/distribution HTTP/1.1
Host: cloudfront.amazonaws.com
Date: Thu, 14 Aug 2008 17:08:48 GMT
Authorization: AWS AKIAIOSFODNN7EXAMPLE:111111112222222jPXo7+e/YSu0g=
[Other required headers]

<?xml version="1.0" encoding="UTF-8"?>
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2012-07-01/">
   <CallerReference>example.com2012-04-11-5:09pm</CallerReference>
   <Aliases>
      ...
   </Aliases>
   <DefaultRootObject>index.html</DefaultRootObject>
   <Origins>
      ...
   </Origins>
   <CacheBehaviors>
      ...
   </CacheBehaviors>
   <Comment>example comment</Comment>
   <Logging>
      ...
   </Logging>
   <PriceClass>PriceClass_All</PriceClass>
   <Enabled>true</Enabled>
</DistributionConfig>

Authentication Errors

If the signature we create based on your request and Secret Access Key doesn't match the signature you sent in the request, we return the following error.

<ErrorResponse xmlns="http://cloudfront.amazonaws.com/doc/2012-07-01/">
   <Error>
      <Type>Sender</Type>
      <Code>SignatureDoesNotMatch</Code>
      <Message>The request signature we calculated 
        does not match the signature you provided. 
        Check your AWS Secret Access Key and signing
        method. Consult the service documentation for details.
      </Message>
   </Error>
   <RequestId>a1170c87-d04d-47c9-964f-54e1a4883f4e</RequestId>
</ErrorResponse>

Fetching the Date

To avoid replays of your requests, AWS requires the time stamp in the request to be within 15 minutes of the AWS system time. To avoid clock synchronization errors, we recommend you fetch the current date from the CloudFront server and then use that as the time stamp for your request and the string for your signature.

To fetch the date

  • Send an unauthenticated GET request for the date resource.

    GET /date HTTP/1.1
    Host: cloudfront.amazonaws.com

We return the current server date as the value of the Date response header (note that the HTTP status code may or may not be a 200). The date uses the RFC 1123 format (e.g., Wed, 18 Nov 2009 17:08:48 GMT). For more information, go to the RFC 1123 specification.