Generare firme

Questa guida spiega come creare una firma e le funzionalità obbligatorie e facoltative per le firme.

Per creare una firma, è necessario comporre una stringa da firmare, che definiamo un firmato di questa guida. Il valore con segno include i parametri che descrivono i contenuti che stai proteggendo, la data di scadenza del valore firmato e così via via email.

Puoi utilizzare il valore firmato durante la creazione di una stringa per la firma. Creerai un la stringa della firma componendo i parametri per la firma, come una firma con chiave asimmetrica Ed25519 del valore firmato.

Media CDN utilizza la firma finale scritta per proteggere contenuti.

Formati di firma supportati

Media CDN supporta i seguenti formati di richieste firmate.

Formato Comportamento Esempio
Parametri di ricerca (URL esatto)

URL esatto, per concedere l'accesso a un URL specifico.

Esatto:

https://media.example.com/content/manifest.m3u8?
Expires=EXPIRATION
&KeyName=KEY_NAME
&Signature=SIGNATURE

Parametri di query (prefisso URL) La specifica di un URLPrefix ti consente di firmare un prefisso e di aggiungere gli stessi parametri di query a più URL all'interno della generazione di manifest o del player.

Cosa firmare:

URLPrefix=PREFIX
&Expires=EXPIRATION
&KeyName=KEY_NAME
&Signature=SIGNATURE

Sostituisci PREFIX con il prefisso da concedere l'accesso, inclusi schema, host e percorso parziale.

Componente percorso

Prefisso: consente l'accesso a qualsiasi URL con un prefisso precedente al componente "/edge-cache-token=[...]".

Ciò consente agli URL manifest relativi di ereditare automaticamente dell'URL firmato durante il recupero delle risorse secondarie.

https://media.example.com/video/edge-cache-token=Expires=EXPIRATION
&KeyName=KEY_NAME
&Signature=SIGNATURE/manifest_12382131.m3u8
Cookie firmato Prefisso: il cookie consente di accedere a qualsiasi URL con il prefisso specificato nel valore URLPrefix firmato.

Edge-Cache-Cookie:

URLPrefix=PREFIX:
Expires=EXPIRATION:
KeyName=KEY_NAME:
Signature=SIGNATURE

Crea una firma

  1. Crea un valore firmato concatenando una stringa che contiene il valore campi della firma obbligatori e desiderati campi della firma facoltativi.

    Se specificato, URLPrefix deve essere visualizzato per primo, seguito da Expires, KeyName, e gli eventuali parametri facoltativi.

    Separa ogni campo e i parametri con quanto segue:

    • Per i cookie, utilizza i due punti :.
    • Per i parametri di query e i componenti del percorso, utilizza il carattere &&.
  2. Firma il valore firmato con una firma Ed25519.

  3. Aggiungi un separatore di campo (: o &) seguito da Signature= e dalla firma Ed25519 alla fine della stringa.

Crea un URL firmato

I seguenti esempi di codice mostrano come creare in modo programmatico un URL firmato.

Go

Per eseguire l'autenticazione su Media CDN, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

import (
	"crypto/ed25519"
	"encoding/base64"
	"fmt"
	"io"
	"strings"
	"time"
)

// signURL prints the signed URL string for the specified URL and configuration.
func signURL(w io.Writer, url, keyName string, privateKey []byte, expires time.Time) error {
	// url := "http://example.com"
	// keyName := "your_key_name"
	// privateKey := "[]byte{34, 31, ...}"
	// expires := time.Unix(1558131350, 0)

	sep := '?'
	if strings.ContainsRune(url, '?') {
		sep = '&'
	}
	toSign := fmt.Sprintf("%s%cExpires=%d&KeyName=%s", url, sep, expires.Unix(), keyName)
	sig := ed25519.Sign(privateKey, []byte(toSign))

	fmt.Fprintf(w, "%s&Signature=%s", toSign, base64.RawURLEncoding.EncodeToString(sig))

	return nil
}

Python

Per eseguire l'autenticazione su Media CDN, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

import base64
import datetime

import cryptography.hazmat.primitives.asymmetric.ed25519 as ed25519


from six.moves import urllib

def sign_url(
    url: str, key_name: str, base64_key: str, expiration_time: datetime.datetime
) -> str:
    """Gets the Signed URL string for the specified URL and configuration.

    Args:
        url: URL to sign as a string.
        key_name: name of the signing key as a string.
        base64_key: signing key as a base64 encoded byte string.
        expiration_time: expiration time as a UTC datetime object.

    Returns:
        Returns the Signed URL appended with the query parameters based on the
        specified configuration.
    """
    stripped_url = url.strip()
    parsed_url = urllib.parse.urlsplit(stripped_url)
    query_params = urllib.parse.parse_qs(parsed_url.query, keep_blank_values=True)
    epoch = datetime.datetime.utcfromtimestamp(0)
    expiration_timestamp = int((expiration_time - epoch).total_seconds())
    decoded_key = base64.urlsafe_b64decode(base64_key)

    url_pattern = "{url}{separator}Expires={expires}&KeyName={key_name}"

    url_to_sign = url_pattern.format(
        url=stripped_url,
        separator="&" if query_params else "?",
        expires=expiration_timestamp,
        key_name=key_name,
    )

    digest = ed25519.Ed25519PrivateKey.from_private_bytes(decoded_key).sign(
        url_to_sign.encode("utf-8")
    )
    signature = base64.urlsafe_b64encode(digest).decode("utf-8")
    signed_url = "{url}&Signature={signature}".format(
        url=url_to_sign, signature=signature
    )

    return signed_url

Crea un prefisso URL firmato

I seguenti esempi di codice mostrano come creare in modo programmatico un prefisso URL firmato.

Go

Per autenticarti a Media CDN, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

import (
	"crypto/ed25519"
	"encoding/base64"
	"fmt"
	"io"
	"strings"
	"time"
)

// signURLPrefix prints the signed URL string for the specified URL prefix and configuration.
func signURLPrefix(w io.Writer, urlPrefix, keyName string, privateKey []byte, expires time.Time) error {
	// urlPrefix := "https://examples.com"
	// keyName := "your_key_name"
	// privateKey := "[]byte{34, 31, ...}"
	// expires := time.Unix(1558131350, 0)

	sep := '?'
	if strings.ContainsRune(urlPrefix, '?') {
		sep = '&'
	}

	toSign := fmt.Sprintf(
		"URLPrefix=%s&Expires=%d&KeyName=%s",
		base64.RawURLEncoding.EncodeToString([]byte(urlPrefix)),
		expires.Unix(),
		keyName,
	)
	sig := ed25519.Sign(privateKey, []byte(toSign))

	fmt.Fprintf(
		w,
		"%s%c%s&Signature=%s",
		urlPrefix,
		sep,
		toSign,
		base64.RawURLEncoding.EncodeToString(sig),
	)

	return nil
}

Python

Per eseguire l'autenticazione su Media CDN, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

import base64
import datetime

import cryptography.hazmat.primitives.asymmetric.ed25519 as ed25519


from six.moves import urllib

def sign_url_prefix(
    url: str,
    url_prefix: str,
    key_name: str,
    base64_key: str,
    expiration_time: datetime.datetime,
) -> str:
    """Gets the Signed URL string for the specified URL prefix and configuration.

    Args:
        url: URL of request.
        url_prefix: URL prefix to sign as a string.
        key_name: name of the signing key as a string.
        base64_key: signing key as a base64 encoded string.
        expiration_time: expiration time as a UTC datetime object.

    Returns:
        Returns the Signed URL appended with the query parameters based on the
        specified URL prefix and configuration.
    """
    stripped_url = url.strip()
    parsed_url = urllib.parse.urlsplit(stripped_url)
    query_params = urllib.parse.parse_qs(parsed_url.query, keep_blank_values=True)
    encoded_url_prefix = base64.urlsafe_b64encode(
        url_prefix.strip().encode("utf-8")
    ).decode("utf-8")
    epoch = datetime.datetime.utcfromtimestamp(0)
    expiration_timestamp = int((expiration_time - epoch).total_seconds())
    decoded_key = base64.urlsafe_b64decode(base64_key)

    policy_pattern = (
        "URLPrefix={encoded_url_prefix}&Expires={expires}&KeyName={key_name}"
    )
    policy = policy_pattern.format(
        encoded_url_prefix=encoded_url_prefix,
        expires=expiration_timestamp,
        key_name=key_name,
    )

    digest = ed25519.Ed25519PrivateKey.from_private_bytes(decoded_key).sign(
        policy.encode("utf-8")
    )
    signature = base64.urlsafe_b64encode(digest).decode("utf-8")
    signed_url = "{url}{separator}{policy}&Signature={signature}".format(
        url=stripped_url,
        separator="&" if query_params else "?",
        policy=policy,
        signature=signature,
    )
    return signed_url

I seguenti esempi di codice mostrano come creare in modo programmatico un URL firmato cookie.

Crea un componente del percorso firmato

I seguenti esempi di codice mostrano come creare in modo programmatico un percorso firmato di strumento di authoring.

Python

Per autenticarti a Media CDN, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

import base64
import datetime
import hashlib
import hmac

import cryptography.hazmat.primitives.asymmetric.ed25519 as ed25519


def base64_encoder(value: bytes) -> str:
    """
    Returns a base64-encoded string compatible with Media CDN.

    Media CDN uses URL-safe base64 encoding and strips off the padding at the
    end.
    """
    encoded_bytes = base64.urlsafe_b64encode(value)
    encoded_str = encoded_bytes.decode("utf-8")
    return encoded_str.rstrip("=")


def sign_path_component(
    url_prefix: str,
    filename: str,
    key_name: str,
    base64_key: str,
    expiration_time: datetime.datetime,
) -> str:
    """Gets the Signed URL string for the specified URL prefix and configuration.

    Args:
        url_prefix: URL Prefix to sign as a string.
        filename: The filename of the sample request
        key_name: The name of the signing key as a string.
        base64_key: The signing key as a base64 encoded string.
        expiration_time: Expiration time as a UTC datetime object with timezone.

    Returns:
        Returns the Signed URL appended with the query parameters based on the
        specified URL prefix and configuration.
    """

    expiration_duration = expiration_time.astimezone(
        tz=datetime.timezone.utc
    ) - datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc)
    decoded_key = base64.urlsafe_b64decode(base64_key)

    policy_pattern = "{url_prefix}edge-cache-token=Expires={expires}&KeyName={key_name}"
    policy = policy_pattern.format(
        url_prefix=url_prefix,
        expires=int(expiration_duration.total_seconds()),
        key_name=key_name,
    )

    digest = ed25519.Ed25519PrivateKey.from_private_bytes(decoded_key).sign(
        policy.encode("utf-8")
    )
    signature = base64_encoder(digest)

    signed_url = "{policy}&Signature={signature}/{filename}".format(
        policy=policy, signature=signature, filename=filename
    )

    return signed_url

Campi della firma obbligatori

I seguenti campi sono obbligatori per ogni firma:

  • Expires
  • KeyName
  • Signature

Se sono presenti parametri di query, devono essere raggruppati come ultimi parametri nell'URL. Se non diversamente specificato, i nomi dei parametri e i relativi ai valori fanno distinzione tra maiuscole e minuscole.

La tabella seguente spiega ogni parametro:

Nome campo Parametri di firma Valore firmato
Expires Secondi interi trascorsi dall'epoca di Unix (1970-01-01T00:00:00Z) Expires=EXPIRATION_TIME, dopodiché la firma non è più valida.
KeyName Il nome del EdgeCacheKeyset utilizzato per firmare questa richiesta. KeyName si riferisce all'intero set di chiavi, non alle singole chiavi all'interno del set di chiavi stesso. KeyName=EDGE_CACHE_KEYSET
Signature Una versione della firma con codifica Base64. Non applicabile

Campi della firma facoltativi

Se sono presenti parametri di ricerca, devono essere raggruppati come ultimi parametri nell'URL. Se non diversamente specificato, i nomi dei parametri e i relativi ai valori fanno distinzione tra maiuscole e minuscole.

La tabella seguente illustra il nome e i dettagli di ciascun parametro per parametri di firma:

Nome campo Parametri di firma Valore firmato
HeaderName

Il nome di un campo di intestazione della richiesta che deve essere presente nella richiesta.

Deve essere minuscolo quando viene firmato perché i nomi dei campi di intestazione sono sensibile alle maiuscole. Media CDN usa il formato minuscolo dell'intestazione prima di convalidare la firma.

HeaderName=HEADER_NAME
HeaderValue Un valore denominato del campo di intestazione della richiesta che deve essere presente nella richiesta. In genere si tratta di un ID utente o di un altro identificatore opaco. Richieste con HeaderValue ma senza HeaderName sono rifiutato. HeaderValue=HEADER_VALUE
IPRanges

Un elenco di massimo cinque indirizzi IPv4 e IPv6 in formato CIDR per i quali questo URL è valido in formato base64 sicuro per il web. Ad esempio: per specificare gli intervalli IP "192.6.13.13/32,193.5.64.135/32", devi specificare IPRanges=MTkyLjYuMTMuMTMvMzIsMTkzLjUuNjQuMTM1LzMy.

Potrebbe non essere utile includere gli intervalli IP nelle firme quando i client a rischio di migrazioni WAN o di casi in cui il percorso di rete il frontend dell'applicazione è diverso dal percorso di distribuzione. Media CDN rifiuta i client con un HTTP 403 quando si connettono con un indirizzo IP che non fa parte del una richiesta firmata.

Di seguito sono riportati i casi che potrebbero causare la presenza di Media CDN rifiuto dei clienti con un codice HTTP 403:

  • Ambienti a doppio stack (IPv4, IPv6)
  • Migrazione della connessione (da Wi-Fi a rete mobile e da rete mobile a Wi-Fi)
  • Reti mobili che utilizzano Carrier Gateway NAT (CGNAT o CGN)
  • TCP multi-path (MPTCP)

Tutti questi fattori possono contribuire al fatto che un determinato cliente un indirizzo IP non deterministico durante una sessione di riproduzione video. Se l'indirizzo IP del client cambia dopo che hai concesso l'accesso e il client tenta di scaricare un segmento video buffer, ricevono un valore HTTP 403 Media CDN.

IPRanges=BASE_64_IP_RANGES
URLPrefix Il prefisso dell'URL base64 (sicuro per l'URL) a cui concedere l'accesso. Specificare un URLPrefix ti consente di firmare un prefisso e aggiungere la stessa query a più URL nella generazione del player o del manifest. L'URLPrefix è obbligatorio quando si utilizza il cookie firmato formato. URLPrefix=BASE_64_URL_PREFIX