Question

I am having trouble getting Cloudfront videos to play when using a signed url. If I do NOT require a signed URL, everything works fine. Here is the code that signs the url:

function rsa_sha1_sign($policy, $private_key_filename)
{
    $signature = "";

    // load the private key
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    //echo $priv_key;
    $pkeyid = openssl_get_privatekey($priv_key);

    // compute signature
    openssl_sign($policy, $signature, $pkeyid);

    // free the key from memory
    openssl_free_key($pkeyid);
    //echo $signature;
    return $signature;
 }

function url_safe_base64_encode($value)
{
    $encoded = base64_encode($value);
    // replace unsafe characters +, = and / with
    // the safe characters -, _ and ~
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
 }

// No restriction
$keyPairId = "KEYPAIRID-DIST-NOT-REQUIRING-SIGNEDURL";
$download_url = "http://URL-DIST-NOT-REQUIRING-SIGNEDURL.cloudfront.net/myvideo.mp4";

//This is just a flag to aid in switching between the 2 testing distributions
if($restrict) {
    $key_pair_id = "KEYPAIRID-DIST-REQUIRING-SIGNEDURL"";
    $download_url = "http://URL-DIST-REQUIRING-SIGNEDURL.cloudfront.net/myvideo.mp4";
}

$DateLessThan = time() + (24*7*60*60);
$policy = '{"Statement":[{"Resource":"'.$download_url.'","Condition":{"DateLessThan":{"AWS:EpochTime":'.$DateLessThan.'}}}]}';

$private_key_file = "/path/to/privatekey.pem";

$signature = rsa_sha1_sign($policy, $private_key_file);
$signature = url_safe_base64_encode($signature);

$final_url = $download_url.'?Policy='.url_safe_base64_encode($policy).'&Signature='.$signature.'&Key-Pair-Id='.$key_pair_id;

echo $final_url;

In the above, if I use the Cloudfront distribution that requires a signed URL (by passing in $restrict=1) then I get an error, "Video not found". In console I see that the GET request for the video was canceled (Status Text: cancelled... weirdly I see this twice). If I use the Distribution that doe NOT require a signed URL everything works fine and the video loads correctly.

What am I missing? The distributions are identical except for the requiring of the signed URL and they both use the same Amazon S3 bucket source for the video.

The player is flowplayer(HTML5) but since it works fine without the signed url I would assume the player isn't the problem.

Was it helpful?

Solution

Please see my answer here: Amazon S3 signed url not working with flowplayer

Hopefully that will help.

In my case, I needed to remove the "mp4:" prefix before signing the url, and then add it back on again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top