I am setting up a HLS streaming service through cloudfront and implementing several security measures for content protection. I have successfully made it work under http, I can stream video and watch it in my website with a lot of content protection security measures. For more details on how I managed to make it work for http you can consult it in a post I made in drupal.org about secure hls streaming.
But now I need to add https to the formula because some encryption keys for hls encrypted segments are being transmitted, but I am having problems. Now I am working to add https to the formula. I have added a certificate to my site and I have added a different certificate in cludfront because my certificate is not a wildcard one.
My site certificate works for subdomain.mydomain.com
My cloudfront certificate is for *.mydomain.com
My cloudfront distribution has a cname of cdn.mydomain.com
When I create the cookie I set the secure parameter to true in the call (6th parameter after domain):
setcookie($name, $value, strtotime('+1 hour'), "/", ".mydomain.com", true, true);
But when I try to access some test data in my site
if (readfile('https://cdn.mydomain.com/privacy_test.txt')==0)
print "Error in cdn access";
I don't see the contents of the file in my website, but the error message.
So it seems I need more things to do to make cloudfront aws signed cookies work under https. Any help?
If you want to receive cookies at your origin but you don't want CloudFront to cache the Set-Cookie headers in your origin's responses, configure your origin to add a Cache-Control header with a no-cache directive that specifies Set-Cookie as a field name. For example: Cache-Control: no-cache="Set-Cookie" .
In CloudFront, a signed URL allow access to a path. Therefore, if the user has a valid signature, he can access it, no matter the origin. In S3, a signed URL issue a request as the signer user.
Simply setting the $secure
parameter of setcookie()
does not create a signed cookie. The process to create a signed cookie is a bit complicated. First, review Using Signed Cookies, specifically the Canned and Custom policy sections. You will need to familiarize yourself with creating a Policy, base64encoding that Policy and creating a Signature from the encoded policy.
Leveraging the code examples outlined in here, I then use the following code in a few of my applications to set the cookies:
public static function getCustomSignedCookies()
{
$domain = '.' . explode('.', apache_request_headers()['Host'], 2)[1];
$dt = new DateTime();
$dt->add(new DateInterval('P1Y')); // 1 year
$expires = $dt->getTimestamp();
$url = Config::get('cloudfront_url') . '/*';
$policy = self::getCustomPolicy($url, $expires);
$encodedPolicy = self::url_safe_base64_encode($policy);
$signature = self::getSignature($policy);
$cookies = [
[
'name' => 'CloudFront-Policy'
, 'value' => $encodedPolicy
, 'expires' => $expires
, 'path' => '/'
, 'domain' => $domain
, 'secure' => true
, 'httpOnly' => true
],
[
'name' => 'CloudFront-Signature'
, 'value' => $signature
, 'expires' => $expires
, 'path' => '/'
, 'domain' => $domain
, 'secure' => true
, 'httpOnly' => true
],
[
'name' => 'CloudFront-Key-Pair-Id'
, 'value' => self::$keyPair
, 'expires' => $expires
, 'path' => '/'
, 'domain' => $domain
, 'secure' => true
, 'httpOnly' => true
]
];
return $cookies;
}
public static function setCloudFrontCookies()
{
ob_start();
foreach (self::getCustomSignedCookies() as $cookie)
{
setcookie
(
$cookie['name']
, $cookie['value']
, $cookie['expires']
, $cookie['path']
, $cookie['domain']
, $cookie['secure']
, $cookie['httpOnly']
);
}
ob_end_flush();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With