Tokens generieren

In diesem Leitfaden werden die erforderlichen und optionalen -Felder für Tokens.

Um ein Token zu erstellen, erstellen Sie eine zu signierende Zeichenfolge, die wir als signierte Wert in diesem Leitfaden. Der vorzeichenbehaftete Wert enthält Parameter, die den Inhalte, die Sie schützen, die Ablaufzeit des signierten Werts usw. weiter.

Sie verwenden den signierten Wert beim Erstellen eines Tokenstrings. Sie erstellen ein Tokenstrings durch Erstellen der Parameter für das Token, z. B. Einen symmetrischen Hash-basierten Nachrichtenauthentifizierungscode (HMAC) des signierten Wert.

Media CDN verwendet das Token für die endgültige Erstellung, um Ihre Inhalte.

Token erstellen

  1. Erstellen Sie einen signierten Wert, indem Sie einen String verketten, der den Parameter Erforderliche Token-Felder und gewünschte optionale Tokens enthalten. Trennen Sie die einzelnen Felder und Parameter durch als Tilde-Zeichen ~.

  2. Signieren Sie den signierten Wert entweder mit einer Ed25519-Signatur oder einem symmetrischen Schlüssel. HMAC

  3. Erstellen Sie das Token, indem Sie einen String verketten, der die erforderlichen Token-Felder und optionale Token-Felder. Trennen Sie die einzelnen Felder und Parameter mit dem Tildezeichen ~.

    Beim Erstellen des Tokens sind die Werte für jeden der Parameter die ist gleich zwischen dem signierten Wert und dem Tokenstring, wobei Folgendes verwendet wird: Ausnahmen:

    • FullPath
    • Headers

Das folgende Codebeispiel zeigt, wie Sie ein Token programmatisch erstellen können:

Python

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Media CDN zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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_token(
    base64_key: bytes,
    signature_algorithm: str,
    start_time: datetime.datetime = None,
    expiration_time: datetime.datetime = None,
    url_prefix: str = None,
    full_path: str = None,
    path_globs: str = None,
    session_id: str = None,
    data: str = None,
    headers: str = None,
    ip_ranges: str = None,
) -> str:
    """Gets the Signed URL Suffix string for the Media CDN' Short token URL requests.
    One of (`url_prefix`, `full_path`, `path_globs`) must be included in each input.
    Args:
        base64_key: Secret key as a base64 encoded string.
        signature_algorithm: Algorithm can be either `SHA1` or `SHA256` or `Ed25519`.
        start_time: Start time as a UTC datetime object.
        expiration_time: Expiration time as a UTC datetime object. If None, an expiration time 1 hour from now will be used.
        url_prefix: the URL prefix to sign, including protocol.
                    For example: http://example.com/path/ for URLs under /path or http://example.com/path?param=1
        full_path:  A full path to sign, starting with the first '/'.
                    For example: /path/to/content.mp4
        path_globs: a set of ','- or '!'-delimited path glob strings.
                    For example: /tv/*!/film/* to sign paths starting with /tv/ or /film/ in any URL.
        session_id: a unique identifier for the session
        data: data payload to include in the token
        headers: header name and value to include in the signed token in name=value format.  May be specified more than once.
                    For example: [{'name': 'foo', 'value': 'bar'}, {'name': 'baz', 'value': 'qux'}]
        ip_ranges: A list of comma separated ip ranges. Both IPv4 and IPv6 ranges are acceptable.
                    For example: "203.0.113.0/24,2001:db8:4a7f:a732/64"

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

    decoded_key = base64.urlsafe_b64decode(base64_key)
    algo = signature_algorithm.lower()

    # For most fields, the value we put in the token and the value we must sign
    # are the same.  The FullPath and Headers use a different string for the
    # value to be signed compared to the token.  To illustrate this difference,
    # we'll keep the token and the value to be signed separate.
    tokens = []
    to_sign = []

    # check for `full_path` or `path_globs` or `url_prefix`
    if full_path:
        tokens.append("FullPath")
        to_sign.append(f"FullPath={full_path}")
    elif path_globs:
        path_globs = path_globs.strip()
        field = f"PathGlobs={path_globs}"
        tokens.append(field)
        to_sign.append(field)
    elif url_prefix:
        field = "URLPrefix=" + base64_encoder(url_prefix.encode("utf-8"))
        tokens.append(field)
        to_sign.append(field)
    else:
        raise ValueError(
            "User Input Missing: One of `url_prefix`, `full_path` or `path_globs` must be specified"
        )

    # check & parse optional params
    if start_time:
        epoch_duration = start_time.astimezone(
            tz=datetime.timezone.utc
        ) - datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc)
        field = f"Starts={int(epoch_duration.total_seconds())}"
        tokens.append(field)
        to_sign.append(field)

    if not expiration_time:
        expiration_time = datetime.datetime.now() + datetime.timedelta(hours=1)
        epoch_duration = expiration_time.astimezone(
            tz=datetime.timezone.utc
        ) - datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc)
    else:
        epoch_duration = expiration_time.astimezone(
            tz=datetime.timezone.utc
        ) - datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc)
    field = f"Expires={int(epoch_duration.total_seconds())}"
    tokens.append(field)
    to_sign.append(field)

    if session_id:
        field = f"SessionID={session_id}"
        tokens.append(field)
        to_sign.append(field)

    if data:
        field = f"Data={data}"
        tokens.append(field)
        to_sign.append(field)

    if headers:
        header_names = []
        header_pairs = []
        for each in headers:
            header_names.append(each["name"])
            header_pairs.append("%s=%s" % (each["name"], each["value"]))
        tokens.append(f"Headers={','.join(header_names)}")
        to_sign.append(f"Headers={','.join(header_pairs)}")

    if ip_ranges:
        field = f"IPRanges={base64_encoder(ip_ranges.encode('ascii'))}"
        tokens.append(field)
        to_sign.append(field)

    # generating token
    to_sign = "~".join(to_sign)
    to_sign_bytes = to_sign.encode("utf-8")
    if algo == "ed25519":
        digest = ed25519.Ed25519PrivateKey.from_private_bytes(decoded_key).sign(
            to_sign_bytes
        )
        tokens.append("Signature=" + base64_encoder(digest))
    elif algo == "sha256":
        signature = hmac.new(
            decoded_key, to_sign_bytes, digestmod=hashlib.sha256
        ).hexdigest()
        tokens.append("hmac=" + signature)
    elif algo == "sha1":
        signature = hmac.new(
            decoded_key, to_sign_bytes, digestmod=hashlib.sha1
        ).hexdigest()
        tokens.append("hmac=" + signature)
    else:
        raise ValueError(
            "Input Missing Error: `signature_algorithm` can only be one of `sha1`, `sha256` or `ed25519`"
        )
    return "~".join(tokens)

Java

Richten Sie Standardanmeldedaten für Anwendungen ein, um sich bei Media CDN zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.signers.Ed25519Signer;
import org.bouncycastle.util.encoders.Hex;

public class DualToken {

  public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
    // TODO(developer): Replace these variables before running the sample.
    // Secret key as a base64 encoded string.
    byte[] base64Key = new byte[]{};
    // Algorithm can be one of these: SHA1, SHA256, or Ed25519.
    String signatureAlgorithm = "ed25519";
    // (Optional) Start time as a UTC datetime object.
    DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
    Optional<Instant> startTime = Optional.empty();
    // Expiration time as a UTC datetime object.
    // If None, an expiration time that's an hour after the current time is used.
    Instant expiresTime = Instant.from(formatter.parse("2022-09-13T12:00:00Z"));

    // ONE OF (`urlPrefix`, `fullPath`, `pathGlobs`) must be included in each input.
    // The URL prefix and protocol to sign.
    // For example: http://example.com/path/ for URLs under /path or http://example.com/path?param=1
    Optional<String> urlPrefix = Optional.empty();
    // A full path to sign, starting with the first '/'.
    // For example: /path/to/content.mp4
    Optional<String> fullPath = Optional.of("http://10.20.30.40/");
    // A set of path glob strings delimited by ',' or '!'.
    // For example: /tv/*!/film/* to sign paths starting with /tv/ or /film/ in any URL.
    Optional<String> pathGlobs = Optional.empty();

    // (Optional) A unique identifier for the session.
    Optional<String> sessionId = Optional.empty();
    // (Optional) Data payload to include in the token.
    Optional<String> data = Optional.empty();
    // (Optional) Header name and value to include in the signed token in name=value format.
    // May be specified more than once.
    // For example: [{'name': 'foo', 'value': 'bar'}, {'name': 'baz', 'value': 'qux'}]
    Optional<List<Header>> headers = Optional.empty();
    // (Optional) A list of comma-separated IP ranges. Both IPv4 and IPv6 ranges are acceptable.
    // For example: "203.0.113.0/24,2001:db8:4a7f:a732/64"
    Optional<String> ipRanges = Optional.empty();

    DualToken.signToken(
        base64Key,
        signatureAlgorithm,
        startTime,
        expiresTime,
        urlPrefix,
        fullPath,
        pathGlobs,
        sessionId,
        data,
        headers,
        ipRanges);
  }

  // Gets the signed URL suffix string for the Media CDN short token URL requests.
  // Result:
  //     The signed URL appended with the query parameters based on the
  // specified URL prefix and configuration.
  public static void signToken(
      byte[] base64Key, String signatureAlgorithm, Optional<Instant> startTime,
      Instant expirationTime, Optional<String> urlPrefix, Optional<String> fullPath,
      Optional<String> pathGlobs, Optional<String> sessionId, Optional<String> data,
      Optional<List<Header>> headers, Optional<String> ipRanges)
      throws NoSuchAlgorithmException, InvalidKeyException {

    String field = "";
    byte[] decodedKey = Base64.getUrlDecoder().decode(base64Key);

    // For most fields, the value in the token and the value to sign
    // are the same. Compared to the token, the FullPath and Headers
    // use a different string for the value to sign. To illustrate this difference,
    // we'll keep the token and the value to be signed separate.
    List<String> tokens = new ArrayList<>();
    List<String> toSign = new ArrayList<>();

    // Check for `fullPath` or `pathGlobs` or `urlPrefix`.
    if (fullPath.isPresent()) {
      tokens.add("FullPath");
      toSign.add(String.format("FullPath=%s", fullPath.get()));
    } else if (pathGlobs.isPresent()) {
      field = String.format("PathGlobs=%s", pathGlobs.get().trim());
      tokens.add(field);
      toSign.add(field);
    } else if (urlPrefix.isPresent()) {
      field = String.format("URLPrefix=%s",
          base64Encoder(urlPrefix.get().getBytes(StandardCharsets.UTF_8)));
      tokens.add(field);
      toSign.add(field);
    } else {
      throw new IllegalArgumentException(
          "User Input Missing: One of `urlPrefix`, `fullPath` or `pathGlobs` must be specified");
    }

    // Check & parse optional params.
    long epochDuration;
    if (startTime.isPresent()) {
      epochDuration = ChronoUnit.SECONDS.between(Instant.EPOCH, startTime.get());
      field = String.format("Starts=%s", epochDuration);
      tokens.add(field);
      toSign.add(field);
    }

    if (expirationTime == null) {
      expirationTime = Instant.now().plus(1, ChronoUnit.HOURS);
    }
    epochDuration = ChronoUnit.SECONDS.between(Instant.EPOCH, expirationTime);
    field = String.format("Expires=%s", epochDuration);
    tokens.add(field);
    toSign.add(field);

    if (sessionId.isPresent()) {
      field = String.format("SessionID=%s", sessionId.get());
      tokens.add(field);
      toSign.add(field);
    }

    if (data.isPresent()) {
      field = String.format("Data=%s", data.get());
      tokens.add(field);
      toSign.add(field);
    }

    if (headers.isPresent()) {
      List<String> headerNames = new ArrayList<>();
      List<String> headerPairs = new ArrayList<>();

      for (Header entry : headers.get()) {
        headerNames.add(entry.getName());
        headerPairs.add(String.format("%s=%s", entry.getName(), entry.getValue()));
      }
      tokens.add(String.format("Headers=%s", String.join(",", headerNames)));
      toSign.add(String.format("Headers=%s", String.join(",", headerPairs)));
    }

    if (ipRanges.isPresent()) {
      field = String.format("IPRanges=%s",
          base64Encoder(ipRanges.get().getBytes(StandardCharsets.US_ASCII)));
      tokens.add(field);
      toSign.add(field);
    }

    // Generate token.
    String toSignJoined = String.join("~", toSign);
    byte[] toSignBytes = toSignJoined.getBytes(StandardCharsets.UTF_8);
    String algorithm = signatureAlgorithm.toLowerCase();

    if (algorithm.equalsIgnoreCase("ed25519")) {
      Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(decodedKey, 0);
      Ed25519Signer signer = new Ed25519Signer();
      signer.init(true, privateKey);
      signer.update(toSignBytes, 0, toSignBytes.length);
      byte[] signature = signer.generateSignature();
      tokens.add(String.format("Signature=%s", base64Encoder(signature)));
    } else if (algorithm.equalsIgnoreCase("sha256")) {
      String sha256 = "HmacSHA256";
      Mac mac = Mac.getInstance(sha256);
      SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, sha256);
      mac.init(secretKeySpec);
      byte[] signature = mac.doFinal(toSignBytes);
      tokens.add(String.format("hmac=%s", Hex.toHexString(signature)));
    } else if (algorithm.equalsIgnoreCase("sha1")) {
      String sha1 = "HmacSHA1";
      Mac mac = Mac.getInstance(sha1);
      SecretKeySpec secretKeySpec = new SecretKeySpec(decodedKey, sha1);
      mac.init(secretKeySpec);
      byte[] signature = mac.doFinal(toSignBytes);
      tokens.add(String.format("hmac=%s", Hex.toHexString(signature)));
    } else {
      throw new Error(
          "Input Missing Error: `signatureAlgorithm` can only be one of `sha1`, `sha256` or "
              + "`ed25519`");
    }
    // The signed URL appended with the query parameters based on the
    // specified URL prefix and configuration.
    System.out.println(String.join("~", tokens));
  }

  // Returns a base64-encoded string compatible with Media CDN.
  // Media CDN uses URL-safe base64 encoding and strips off the padding at the
  // end.
  public static String base64Encoder(byte[] value) {
    byte[] encodedBytes = Base64.getUrlEncoder().withoutPadding().encode(value);
    return new String(encodedBytes, StandardCharsets.UTF_8);
  }

  public static class Header {

    private String name;
    private String value;

    public Header(String name, String value) {
      this.name = name;
      this.value = value;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getValue() {
      return value;
    }

    public void setValue(String value) {
      this.value = value;
    }

    @Override
    public String toString() {
      return "Header{"
          + "name='" + name + '\''
          + ", value='" + value + '\''
          + '}';
    }
  }

}

In den folgenden Abschnitten werden die von Tokens verwendeten Felder beschrieben.

Erforderliche Tokenfelder

Die folgenden Felder sind für jedes Token erforderlich:

  • Expires
  • Einer der folgenden Typen: <ph type="x-smartling-placeholder">
      </ph>
    • PathGlobs
    • URLPrefix
    • FullPath
  • Eine der folgenden Möglichkeiten: <ph type="x-smartling-placeholder">
      </ph>
    • Signature
    • hmac

Sofern nicht anders angegeben, wird bei Parameternamen und ihren Werten zwischen Groß- und Kleinschreibung unterschieden.

In der folgenden Tabelle werden die einzelnen Parameter erläutert:

Feldname / Aliasse Tokenparameter Signierter Wert

Expires

exp

Ganzzahlige Sekunden, die seit der Unix-Epoche vergangen sind (1970-01-01T00:00:00Z) Expires=EXPIRATION_TIME, danach wird der Token ist nicht mehr gültig.

PathGlobs

paths, acl

Eine Liste mit bis zu fünf Pfadsegmenten, auf die Zugriff gewährt werden soll. Die Segmente können durch Kommas (,) oder Ausrufezeichen getrennt werden. (!), aber nicht beides.

PathGlobs unterstützt Platzhalterzeichen in Pfaden mithilfe von Sternchen (*) und Fragezeichen (?) Eine einzelne Sternchen (*) für eine beliebige Anzahl von Pfadsegmenten, im Gegensatz zur Musterabgleichssyntax für pathMatchTemplate.

Pfadparameter, die durch Semikolons (;) gekennzeichnet sind, sind nicht zulässig, da sie beim Abgleich für Mehrdeutigkeit sorgen.

Achten Sie daher darauf, dass Ihre URL Folgendes nicht enthält: Sonderzeichen: ,!*?;

PathGlobs=PATHS
URLPrefix

Eine websichere Base64-codierte URL mit dem Protokoll http:// oder https:// bis zu einem Punkt deines Auswahl.

Einige gültige URLPrefix-Werte für „https://beispiel.de/foo/bar.ts“ sind „https://beispiel.de“, „https://beispiel.de/foo“ und „https://beispiel.de/foo/bar“.

URLPrefix=BASE_64_URL_PREFIX
FullPath – Wenn Sie FullPath in einem Token angeben, dürfen Sie das Attribut nicht duplizieren Pfad, den Sie im signierten Wert angegeben haben. Fügen Sie in ein Token das Feld ohne =. FullPath=FULL_PATH_TO_OBJECT
Signature Eine websichere Base64-codierte Version der Signatur. Nicht zutreffend
hmac Eine websichere Base64-codierte Version des HMAC-Werts. Nicht zutreffend

Platzhaltersyntax PathGlobs

In der folgenden Tabelle wird die Syntax des Platzhalters PathGlobs erläutert.

Operator Stimmt überein mit Beispiele
* (Sternchen) Stimmt mit null oder mehr Zeichen im URL-Pfad überein, einschließlich Schrägstrich (/) Zeichen.
  • /videos/* stimmt mit jedem Pfad überein, der mit /videos/.
  • /videos/s*/4k/* stimmt mit /videos/s/4k/ und /videos/s01/4k/main.m3u8
  • /manifests/*/4k/* Übereinstimmungen /manifests/s01/4k/main.m3u8 und /manifests/s01/e01/4k/main.m3u8 Stimmt nicht überein /manifests/4k/main.m3u8
? (Fragezeichen) Stimmt mit einem einzelnen Zeichen in den URL-Pfad ohne Schrägstrich (/) Zeichen. /videos/s?main.m3u8 Übereinstimmungen /videos/s1main.m3u8. Keine Übereinstimmung /videos/s01main.m3u8 oder /videos/s/main.m3u8.

Globs müssen entweder mit einem Sternchen (*) oder einem Schrägstrich (/) beginnen für URL-Pfade.

Da * und /* mit allen URL-Pfaden übereinstimmen, raten wir davon ab, Verwenden Sie eines der beiden in Ihren signierten Tokens. Für maximalen Schutz dass Ihre Globs mit den Inhalten übereinstimmen, auf die Sie Zugriff gewähren möchten.

Optionale Tokenfelder

Sofern nicht anders angegeben, wird bei Parameternamen und ihren Werten zwischen Groß- und Kleinschreibung unterschieden.

In der folgenden Tabelle werden die Parameternamen, etwaige Aliasse und Details für Optionale Parameter:

Feldname / Aliasse Parameter Signierter Wert

Starts

st

Ganzzahlsekunden seit der Unix-Epoche (1970-01-01T00:00:00Z) Starts=START_TIME
IPRanges

Eine Liste mit bis zu fünf IPv4- und IPv6-Adressen im CIDR-Format für für die diese URL im websicheren Base64-Format gültig ist. Beispiel: zum Angeben der IP-Bereiche "192.6.13.13/32,193.5.64.135/32", geben Sie IPRanges=MTkyLjYuMTMuMTMvMzIsMTkzLjUuNjQuMTM1LzMy

IPRanges können in Tokens nicht hilfreich sein, wenn Clients Es besteht das Risiko von WAN-Migrationen oder Fällen, bei denen der Netzwerkpfad zu Ihrem dass sich das Frontend der Anwendung vom Bereitstellungspfad unterscheidet. Media CDN lehnt Kunden mit einem HTTP 403 ab wenn sie eine Verbindung mit einer IP-Adresse herstellen, die nicht Teil des unterzeichnete Anfrage.

Die folgenden Fälle können zu Media CDN führen Kunden mit dem Code HTTP 403 ablehnen:

  • Dual-Stack-Umgebungen (IPv4, IPv6)
  • Verbindungsmigration (WLAN-zu-Mobilfunk und Mobilfunk-zu-WLAN)
  • Mobilfunknetze, die Carrier Gateway NAT (CGNAT oder CGN) verwenden
  • Multi-Path-TCP (MPTCP)

All diese Faktoren können dazu beitragen, dass ein bestimmter Client während einer Videowiedergabesitzung eine nicht-deterministische IP-Adresse hat. Wenn die Client-IP-Adresse ändert sich, nachdem Sie Zugriff gewährt haben, und Client versucht, ein Videosegment in die Wiedergabe herunterzuladen. erhält er eine HTTP 403 von Media CDN.

IPRanges=BASE_64_IP_RANGES

SessionID

id

Beliebiger String, der für die Analyse oder Wiedergabe von Protokollen nützlich ist Tracing von Daten.

Verwenden Sie %-codiert oder websicher, um das Erstellen eines ungültigen Tokens zu vermeiden base64-codierte Strings. Die folgenden Zeichen dürfen nicht für SessionID, da sie dazu führen, dass das Token ungültig wird: „~“, „&“ oder „ “ (Leerzeichen).

SessionID=SESSION_ID_VALUE

Data

data, payload

Beliebiger String, der für die Loganalyse nützlich ist.

Verwenden Sie %-codiert oder websicher, um das Erstellen eines ungültigen Tokens zu vermeiden base64-codierte Strings. Die folgenden Zeichen dürfen nicht für Data, da sie dazu führen, dass das Token ungültig wird: „~“, „&“ oder „ “ (Leerzeichen).

data=DATA_VALUE
Headers Eine durch Kommas getrennte Liste von Header-Feldnamen. Headernamen sind Groß- und Kleinschreibung für Lookups in der Anfrage nicht berücksichtigt wird. Headernamen in der signierten Datei wird zwischen Groß- und Kleinschreibung unterschieden. Wenn eine Überschrift fehlt, ist der Wert der leere Wert . Mehrere Kopien einer Kopfzeile sind erforderlich, durch Kommas verkettet sind. Headers=HEADER_1_NAME=HEADER_1_EXPECTED_VALUE, HEADER_2_NAME=HEADER_2_EXPECTED_VALUE

Beispiele

Die folgenden Abschnitte enthalten Beispiele zum Generieren von Tokens.

Beispiel mit FullPath

Sehen Sie sich das folgende Beispiel mit dem Feld FullPath an:

  • Angeforderter Artikel: http://example.com/tv/my-show/s01/e01/playlist.m3u8
  • Ablaufzeit: 160000000

Der vorzeichenbehaftete Wert ist:

Expires=160000000~FullPath=/tv/my-show/s01/e01/playlist.m3u8

Signieren Sie den signierten Wert entweder mit einer Ed25519-Signatur oder mit einem symmetrischen Schlüssel-HMAC an.

Die folgenden Beispieltokens werden aus einem signierten Wert erstellt:

Ed25519-Signatur

Expires=160000000~FullPath~Signature=SIGNATURE_OF_SIGNED_VALUE

Dabei ist SIGNATURE_OF_SIGNED_VALUE die ED25519-Signatur der signierten Wert erstellt.

Symmetrischer Schlüssel-HMAC

Expires=160000000~FullPath~hmac=HMAC_OF_SIGNED_VALUE

Dabei ist HMAC_OF_SIGNED_VALUE der HMAC mit dem symmetrischen Schlüssel den zuvor erstellten Wert.

In den vorherigen Beispielen wird FullPath im Token angegeben, aber der Wert aus dem Pfad, der im Wert mit Vorzeichen angegeben ist, nicht wiederholt wird. So können Sie den vollständigen Pfad der Anfrage signieren, ohne die Anfrage im Token zu duplizieren.

Beispiel mit URLPrefix

Sehen Sie sich das folgende Beispiel mit dem Feld URLPrefix an:

  • Angeforderter Artikel: http://example.com/tv/my-show/s01/e01/playlist.m3u8
  • Ablaufzeit: 160000000

Der vorzeichenbehaftete Wert ist:

Expires=160000000~URLPrefix=aHR0cDovL2V4YW1wbGUuY29tL3R2L215LXNob3cvczAxL2UwMS9wbGF5bGlzdC5tM3U4

Im vorherigen Beispiel haben wir den Pfad zum angeforderten Element ersetzt. http://example.com/tv/my-show/s01/e01/playlist.m3u8 durch den Pfad zum Element im websicheren Base64-Format, aHR0cDovL2V4YW1wbGUuY29tL3R2L215LXNob3cvczAxL2UwMS9wbGF5bGlzdC5tM3U4.

Signieren Sie den signierten Wert entweder mit einer Ed25519-Signatur oder mit einem symmetrischen Schlüssel-HMAC an.

Die folgenden Beispieltokens werden aus einem signierten Wert erstellt:

Ed25519-Signatur

Expires=160000000~URLPrefix=aHR0cDovL2V4YW1wbGUuY29tL3R2L215LXNob3cvczAxL2UwMS9wbGF5bGlzdC5tM3U4~Signature=SIGNATURE_OF_SIGNED_VALUE

Dabei ist SIGNATURE_OF_SIGNED_VALUE die ED25519-Signatur der signierten Wert erstellt.

Symmetrischer Schlüssel-HMAC

Expires=160000000~URLPrefix=aHR0cDovL2V4YW1wbGUuY29tL3R2L215LXNob3cvczAxL2UwMS9wbGF5bGlzdC5tM3U4~hmac=HMAC_OF_SIGNED_VALUE

Dabei ist HMAC_OF_SIGNED_VALUE der HMAC mit dem symmetrischen Schlüssel den zuvor erstellten Wert.

Beispiel mit Headers

Sehen Sie sich das folgende Beispiel mit dem Feld Headers an:

  • Angeforderter Artikel: http://example.com/tv/my-show/s01/e01/playlist.m3u8
  • Ablaufzeit: 160000000
  • PathGlobs-Wert: *
  • Erwartete Anfrageheader: <ph type="x-smartling-placeholder">
      </ph>
    • user-agent: browser
    • accept: text/html

Der vorzeichenbehaftete Wert ist:

Expires=160000000~PathGlobs=*~Headers=user-agent=browser,accept=text/html

Signieren Sie den signierten Wert entweder mit einer Ed25519-Signatur oder mit einem symmetrischen Schlüssel-HMAC an.

Die folgenden Beispieltokens werden aus einem signierten Wert erstellt:

Ed25519-Signatur

Expires=160000000~PathGlobs=*~Headers=user-agent,accept~Signature=SIGNATURE_OF_SIGNED_VALUE

Dabei ist SIGNATURE_OF_SIGNED_VALUE die ED25519-Signatur der signierten Wert erstellt.

Symmetrischer Schlüssel-HMAC

Expires=160000000~PathGlobs=*~Headers=user-agent,accept~hmac=HMAC_OF_SIGNED_VALUE

Dabei ist HMAC_OF_SIGNED_VALUE der HMAC mit dem symmetrischen Schlüssel den zuvor erstellten Wert.

In den vorherigen Beispielen wird Headers=user-agent,accept im Token bereitgestellt. aber die erwarteten Headerwerte werden aus dem signierten Wert nicht wiederholt. Dadurch können bestimmte Schlüssel/Wert-Paare des Anfrageheaders signieren, ohne die Werte zu duplizieren im Token.