Erstellen einer URL-Signatur mit PHP
Auf allen Webservern, auf denen PHP ausgeführt wird, kann dieser PHP-Beispielcode zum Erstellen von Richtlinienanweisungen und Signaturen für private CloudFront-Distributionen verwendet werden. Im vollständigen Beispiel wird eine funktionierende Webseite mit signierten URL-Links erstellt, die einen Videostream mit CloudFront-Streaming wiedergeben. Sie können das vollständige Beispiel aus der Datei demo-php.zip herunterladen.
Hinweise
-
Das Erstellen einer URL-Signatur ist nur ein Teil der Bereitstellung privater Inhalte über eine signierte URL. Weitere Informationen zum gesamten Prozess finden Sie unter Verwenden signierter URLs.
-
Sie können signierte URLs auch mithilfe der
UrlSigner-Klasse im AWS SDK für PHP erstellen. Weitere Informationen finden Sie unter Class UrlSigner in der API-Referenz zu AWS SDK für PHP.
Themen
In den folgenden Abschnitten wird das Codebeispiel in einzelne Teile unterteilt. Sie finden das Beispiel für vollständigen Code unten.
Erstellen der RSA-SHA-1-Signatur
Dieses Codebeispiel führt Folgendes aus:
-
Die Funktion
rsa_sha1_signhasht und signiert die Richtlinienanweisung. Die erforderlichen Argumente sind eine Richtlinienanweisung und der private Schlüssel, der einem öffentlichen Schlüssel entspricht, der sich in einer vertrauenswürdigen Schlüsselgruppe für Ihre Distribution befindet. -
Als Nächstes erstellt die Funktion
url_safe_base64_encodeeine URL-sichere Version der Signatur.
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); $pkeyid = openssl_get_privatekey($priv_key); // compute signature openssl_sign($policy, $signature, $pkeyid); // free the key from memory openssl_free_key($pkeyid); 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); }
Der folgende Codeausschnitt verwendet die Funktionen get_canned_policy_stream_name() und get_custom_policy_stream_name(), um eine vorgefertigte und benutzerdefinierte Richtlinie zu erstellen. CloudFront verwendet die Richtlinien, um die URL für das Streaming des Videos zu erstellen, einschließlich der Angabe der Ablaufzeit.
Anschließend können Sie anhand einer vordefinierten Richtlinie oder einer benutzerdefinierten Richtlinie festlegen, wie der Zugriff auf Ihre Inhalte verwaltet werden soll. Weitere Informationen darüber, welche Sie wählen sollten, finden Sie im Abschnitt Entscheidung zwischen vordefinierten und benutzerdefinierten Richtlinien für signierte URLs.
Erstellen einer vordefinierten Richtlinie
Der folgende Beispielcode erstellt eine vordefinierte Richtlinienanweisung für die Signatur.
Anmerkung
Die Variable $expires ist ein Datums-/Zeitstempel. Dieser muss eine Ganzzahl sein und keine Zeichenfolge.
function get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires) { // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":'. $expires . '}}}]}'; // the policy contains characters that cannot be part of a URL, so we base64 encode it $encoded_policy = url_safe_base64_encode($canned_policy); // sign the original policy, not the encoded version $signature = rsa_sha1_sign($canned_policy, $private_key_filename); // make the signature safe to be included in a URL $encoded_signature = url_safe_base64_encode($signature); // combine the above into a stream name $stream_name = create_stream_name($video_path, null, $encoded_signature, $key_pair_id, $expires); // URL-encode the query string characters return $stream_name; }
Weitere Informationen zu vordefinierten Richtlinien finden Sie unter Erstellen einer signierten URL mit einer vordefinierten Richtlinie.
Erstellen einer benutzerdefinierten Richtlinie
Der folgende Beispielcode erstellt eine benutzerdefinierte Richtlinienanweisung für die Signatur.
function get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy) { // the policy contains characters that cannot be part of a URL, so we base64 encode it $encoded_policy = url_safe_base64_encode($policy); // sign the original policy, not the encoded version $signature = rsa_sha1_sign($policy, $private_key_filename); // make the signature safe to be included in a URL $encoded_signature = url_safe_base64_encode($signature); // combine the above into a stream name $stream_name = create_stream_name($video_path, $encoded_policy, $encoded_signature, $key_pair_id, null); // URL-encode the query string characters return $stream_name; }
Weitere Informationen zu benutzerdefinierten Richtlinien finden Sie unter Erstellen einer signierten URL mit einer benutzerdefinierten Richtlinie.
Beispiel für vollständigen Code
Der folgende Beispielcode bietet eine vollständige Demo dazu, wie CloudFront-signierte URLs mit PHP erstellt werden. Sie können das vollständige Beispiel aus der Datei demo-php.zip herunterladen.
Im folgenden Beispiel können Sie das Element $policy Condition so anpassen, dass sowohl IPv4- und IPv6-Adressbereiche erlaubt sind. Ein Beispiel finden Sie unter Verwenden von IPv6-Adressen in IAM-Richtlinien im Benutzerhandbuch für Amazon Simple Storage Service.
<?php 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); $pkeyid = openssl_get_privatekey($priv_key); // compute signature openssl_sign($policy, $signature, $pkeyid); // free the key from memory openssl_free_key($pkeyid); 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); } function create_stream_name($stream, $policy, $signature, $key_pair_id, $expires) { $result = $stream; // if the stream already contains query parameters, attach the new query parameters to the end // otherwise, add the query parameters $separator = strpos($stream, '?') == FALSE ? '?' : '&'; // the presence of an expires time means we're using a canned policy if($expires) { $result .= $separator . "Expires=" . $expires . "&Signature=" . $signature . "&Key-Pair-Id=" . $key_pair_id; } // not using a canned policy, include the policy itself in the stream name else { $result .= $separator . "Policy=" . $policy . "&Signature=" . $signature . "&Key-Pair-Id=" . $key_pair_id; } // new lines would break us, so remove them return str_replace('\n', '', $result); } function get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires) { // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":'. $expires . '}}}]}'; // the policy contains characters that cannot be part of a URL, so we base64 encode it $encoded_policy = url_safe_base64_encode($canned_policy); // sign the original policy, not the encoded version $signature = rsa_sha1_sign($canned_policy, $private_key_filename); // make the signature safe to be included in a URL $encoded_signature = url_safe_base64_encode($signature); // combine the above into a stream name $stream_name = create_stream_name($video_path, null, $encoded_signature, $key_pair_id, $expires); // URL-encode the query string characters return $stream_name; } function get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy) { // the policy contains characters that cannot be part of a URL, so we base64 encode it $encoded_policy = url_safe_base64_encode($policy); // sign the original policy, not the encoded version $signature = rsa_sha1_sign($policy, $private_key_filename); // make the signature safe to be included in a URL $encoded_signature = url_safe_base64_encode($signature); // combine the above into a stream name $stream_name = create_stream_name($video_path, $encoded_policy, $encoded_signature, $key_pair_id, null); // URL-encode the query string characters return $stream_name; } // Path to your private key. Be very careful that this file is not accessible // from the web! $private_key_filename = '/home/test/secure/example-priv-key.pem'; $key_pair_id = 'K2JCJMDEHXQW5F'; // Make sure you have "Restrict viewer access" enabled on this path behaviour and using the above Trusted key groups (recommended). $video_path = 'https://example.com/secure/example.mp4'; $expires = time() + 300; // 5 min from now $canned_policy_stream_name = get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires); // Get the viewer real IP from the x-forward-for header as $_SERVER['REMOTE_ADDR'] will return viewer facing IP. An alternative option is to use CloudFront-Viewer-Address header. Note that this header is a trusted CloudFront immutable header. Example format: IP:PORT ("CloudFront-Viewer-Address": "1.2.3.4:12345") $client_ip = $_SERVER['HTTP_X_FORWARDED_FOR']; $policy = '{'. '"Statement":['. '{'. '"Resource":"'. $video_path . '",'. '"Condition":{'. '"IpAddress":{"AWS:SourceIp":"' . $client_ip . '/32"},'. '"DateLessThan":{"AWS:EpochTime":' . $expires . '}'. '}'. '}'. ']' . '}'; $custom_policy_stream_name = get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy); ?> <html> <head> <title>CloudFront</title> </head> <body> <h1>Amazon CloudFront</h1> <h2>Canned Policy</h2> <h3>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?></h3> <br /> <div id='canned'>The canned policy video will be here: <br> <video width="640" height="360" autoplay muted controls> <source src="<?php echo $canned_policy_stream_name; ?>" type="video/mp4"> Your browser does not support the video tag. </video> </div> <h2>Custom Policy</h2> <h3>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?> only viewable by IP <?php echo $client_ip; ?></h3> <div id='custom'>The custom policy video will be here: <br> <video width="640" height="360" autoplay muted controls> <source src="<?php echo $custom_policy_stream_name; ?>" type="video/mp4"> Your browser does not support the video tag. </video> </div> </body> </html>
Zusätzliche Beispiele für URL-Signaturen finden Sie in den folgenden Themen:
Anstatt signierte URLs zur Erstellung der Signatur zu verwenden, können Sie signierte Cookies verwenden. Weitere Informationen finden Sie unter Erstellen signierter Cookies mit PHP.