AWS Developer Tools Blog
Amazon CloudFront Signed URLs and Cookies are now supported in AWS SDK for Java 2.x
We are pleased to announce the general availability of Amazon CloudFront signed URLs and signed cookies in the AWS SDK for Java 2.x. You can now securely serve private content through CloudFront, requiring that your users access your content by using special CloudFront signed URLs or signed cookies. To configure your CloudFront distribution to use this feature, you must specify a trusted key group (recommended) or AWS account as a trusted signer. For more information on setting up and configuring a CloudFront distribution, please see the Developer Guide.
The new SDK 2.x
CloudFrontUtilities component provides the highly-requested signing features that many customers miss from the AWS SDK for Java 1.x. The new APIs in the SDK 2.x APIs have been redesigned with one point of entry for a streamlined usage experience.
You can control access to your content with either signed URLs or signed cookies. Signed URLs allow you to create a new URL that has temporary access to one of your protected CloudFront resources. Signed cookies allow you to create a temporary set of credentials that can be used by your customers to directly access one or many protected CloudFront resources.
Using CloudFront Signing
1) Add a dependency for CloudFront
The first step to getting started is to add the dependency for CloudFront in your project.
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>cloudfront</artifactId> <version>2.18.26</version> <!-- Update to use the latest version. --> </dependency>
We recommend using the most recent version of the SDK.
2) Instantiate the CloudFrontUtilities Class
To instantiate the utility class, you just need to call
import software.amazon.awssdk.services.cloudfront.CloudFrontUtilities; CloudFrontUtilities cloudFrontUtilities = CloudFrontUtilities.create();
3) Create an CloudFrontSignerRequest
Next, you create a
CloudFrontSignerRequest using a builder. A request can be used for both URLs and cookies.
Example #1: Signed Request with Canned Policy
For a URL/cookie with a canned policy, create a
CannedSignerRequest, specifying the resource URL, private key, public key ID, and expiration date.
import software.amazon.awssdk.services.cloudfront.model.CannedSignerRequest; import java.security.PrivateKey; import java.time.Instant; import java.time.temporal.ChronoUnit; Instant expirationDate = Instant.now().plus(7, ChronoUnit.DAYS); String resourceUrl = "https://d1npcfkc2mojrf.cloudfront.net/s3ObjectKey"; String keyPairId = "myKeyPairId"; PrivateKey privateKey = myPrivateKey; // Either PrivateKey or Path can be passed in CannedSignerRequest cannedRequest = CannedSignerRequest.builder() .resourceUrl(resourceUrl) .privateKey(privateKey) .keyPairId(keyPairId) .expirationDate(expirationDate) .build();
Example #2: Signed Request with Custom Policy
For a URL/cookie with a custom policy, create a
CustomSignerRequest, where you can additionally specify the active date and/or the IP range. In this example, we specify both the active date and IP range, though you can choose to specify only one of them.
import software.amazon.awssdk.services.cloudfront.model.CustomSignerRequest; import java.nio.file.Path; import java.time.Instant; import java.time.temporal.ChronoUnit; Instant expirationDate = Instant.now().plus(7, ChronoUnit.DAYS); String resourceUrl = "https://d111111abcdef8.cloudfront.net/s3ObjectKey"; String keyPairId = "myKeyPairId"; Instant activeDate = Instant.now().plus(2, ChronoUnit.DAYS); String ipRange = "192.168.0.1/24"; Path keyFile = myKeyFile; // Either PrivateKey or Path can be passed in CustomSignerRequest customRequest = CustomSignerRequest.builder() .resourceUrl(resourceUrl) .privateKey(keyFile) .keyPairId(keyPairId) .expirationDate(expirationDate) .activeDate(activeDate) //optional .ipRange(ipRange) //optional .build();
4) Create a Signed URL/Signed Cookie
After you generate the request, create the signed URL or signed cookie, from which you can optionally generate an
SdkHttpRequest to be executed by an HTTP client.
Example #1: Signed URL with Canned Policy
To create a
SignedUrl with a canned policy, you just need to call
getSignedUrlWithCannedPolicy(), passing in the
CannedSignerRequest instance. With the
SignedUrl object, you can then call
url() to return a signed URL
import software.amazon.awssdk.services.cloudfront.model.CannedSignerRequest; import software.amazon.awssdk.services.cloudfront.url.SignedUrl; SignedUrl signedUrl = cloudFrontUtilities.getSignedUrlWithCannedPolicy(cannedRequest); // Returns a signed URL String that you can provide to users which will allow them to access your content String url = signedUrl.url()
Example #2: Signed Cookie with Custom Policy
To create a
CookiesForCustomPolicy, you just need to call
getCookiesForCustomPolicy(), passing in the
CustomSignerRequest instance. With the
CookiesForCustomPolicy object, you can call the appropriate methods to return the policy, signature, and key-pair ID cookie header values, which you can then send to the viewer to grant access to your private content.
import software.amazon.awssdk.services.cloudfront.cookie.CookiesForCustomPolicy; import software.amazon.awssdk.services.cloudfront.model.CustomSignerRequest; CookiesForCustomPolicy cookies = cloudFrontUtilities.getCookiesForCustomPolicy(customRequest); // Generates Set-Cookie header values to send to the viewer to allow access String signatureHeaderValue = cookies.signatureHeaderValue(); String keyPairIdHeaderValue = cookies.keyPairIdHeaderValue(); String policyHeaderValue = cookies.policyHeaderValue();
The CloudFront signed URLs/cookies you generated will be valid until the specified expiration dates, after which users will not be able to access your private content. If you wish to revoke access before the expiration date, you just need to remove the trusted signer from the CloudFront distribution.
To completely tear-down and clean up all your resources, you must first disable your CloudFront distribution. Then, you can delete your distribution, key group, and public key in CloudFront. Finally, you can empty and delete your S3 bucket.
In this blog post we went over the basic functionalities of CloudFront signed URLs and signed cookies. We also showed code examples of a signed URL with a canned policy and a signed cookie with a custom policy. To learn more about how to set up and begin using the feature, visit our Developer Guide. If you are curious about how it is implemented, check out the source code on GitHub. As always, we welcome bug reports, feature requests, and pull requests on the aws-sdk-java-v2 GitHub repository.