Zeitlich begrenzten Dateizugriff autorisieren

CloudflareBeginner
Jetzt üben

Einführung

Eine Support-Mitarbeiterin muss kurzzeitig einen privaten synthetischen Export freigeben, ohne den Bucket öffentlich zu machen oder Speicheranmeldedaten weiterzugeben. Sie erstellen eine vorsignierte Download-URL, beobachten ihren Ablauf und weisen nach, dass die zugehörige Signaturberechtigung nicht auf einen anderen, vom Lab verwalteten Bucket zugreifen kann.

Schließen Sie zuerst Organize a Document Bucket und Stream Documents Through a Worker ab. Diese unabhängige VM enthält Node.js 22.22.0, Wrangler 4.131.1 und AWS SDK 3.888.0 in festgelegten Versionen. Für das Konto muss R2 aktiviert sein. Außerdem benötigen Sie die Berechtigung, ein eingeschränktes User-Objekttoken zu erstellen. Es werden nur zwei kleine synthetische Dateien verwendet. Lesen Sie die Informationen zu R2 pricing und presigned access. Eine gekaufte Domain ist nicht erforderlich. Geben Sie erzeugte Links oder Anmeldedaten nicht weiter. Leeren Sie beide Buckets und widerrufen Sie die Tokens dieses Labs, bevor Sie die Umgebung verlassen.

Isolierte Buckets für Zugriffstests erstellen

In diesem Schritt autorisieren Sie diese VM und erstellen einen temporären Bucket. Die Geräteautorisierung bestätigt Ihr Lernkonto. Für die Verwaltung von R2-Buckets wird ein separates API-Token verwendet, das auf dieses Konto beschränkt ist.

Starten Sie Bash für die unten verwendete Befehlssyntax. Wechseln Sie anschließend in das vorbereitete Projekt und prüfen Sie die Werkzeuge. Lassen Sie dieses Terminal geöffnet, damit die Variablen mit den Ressourcennamen erhalten bleiben:

bash
cd /home/labex/project/r2-lab
export PATH="$PWD/.tools/node-v22.22.0-linux-x64/bin:$PATH"
node --version
npx wrangler --version

Autorisieren Sie den angezeigten Gerätecode in Ihrem eigenen Browser. Prüfen Sie vor der Zustimmung das Lernkonto sowie die angeforderten Leseberechtigungen für Konto und Benutzer:

npx wrangler login --device --browser=false --scopes account:read user:read
npx wrangler whoami --json

Erwarten Sie loggedIn: true. Lesen Sie den Kontonamen auch dann aus, wenn nur ein Konto aufgelistet wird. Ersetzen Sie YOUR_ACCOUNT_ID unten durch die tatsächliche 32-stellige ID dieses Kontos. openssl rand -hex 6 erzeugt zwölf zufällige Hexadezimalzeichen, damit dieser Labordurchlauf nicht mit einem früheren Durchlauf kollidiert. Das Here-Dokument schreibt eine standardmäßige Konfigurationsdatei; die Shell setzt Ihre Variablen darin ein.

ACCOUNT_ID=YOUR_ACCOUNT_ID
RUN_ID=$(openssl rand -hex 6)
NAME="labex-c05-r04-$RUN_ID"
BUCKET="$NAME-docs"
cat > wrangler.jsonc <<JSON
{"name":"$NAME","account_id":"$ACCOUNT_ID","compatibility_date":"2026-07-30","r2_buckets":[{"binding":"DOCUMENTS","bucket_name":"$BUCKET"}]}
JSON

Öffnen Sie für die Bucket-Verwaltung auf Ihrem Cloudflare-Profil die Seite API Tokens und erstellen Sie ein benutzerdefiniertes Token mit dem Namen dieses Labs. Erteilen Sie Account → Workers R2 Storage → Edit und beschränken Sie Account Resources auf das Lernkonto, dessen ID Sie gespeichert haben. Legen Sie eine kurze Gültigkeitsdauer fest. Fügen Sie keine anderen Konten und keine themenfremden Berechtigungen hinzu. Diese Berechtigung auf Kontoebene erstellt und löscht Buckets. Das Objekttoken im nächsten Schritt kann dies nicht.

Kopieren Sie das Token einmal in die Eingabeaufforderung dieser ausgeblendeten VM. umask 077 beschränkt den Dateizugriff auf Ihren Benutzer; read -s blendet die Eingabe aus. Die Datei verwendet die standardmäßige Token-Variable von Wrangler und wird von Git ausgeschlossen.

umask 077
read -r -s -p 'R2 management API token: ' R2_MANAGEMENT_TOKEN; printf '\n'
printf 'CLOUDFLARE_API_TOKEN=%s\n' "$R2_MANAGEMENT_TOKEN" > .env.management
unset R2_MANAGEMENT_TOKEN

Verwenden Sie --env-file=.env.management nur für R2-Verwaltungsbefehle. Ein gewöhnlicher whoami-Aufruf prüft weiterhin die Geräteautorisierung der VM.

Setzen Sie --env-file an das Ende jedes Wrangler-Befehls, damit dessen Liste von Dateiargumenten nicht auch den Befehlsnamen erfasst. Wenn Wrangler nach dem Erstellen eines Buckets anbietet, eine Bindung zur Konfiguration hinzuzufügen, geben Sie n ein und drücken Sie die Eingabetaste. Die vorgesehene Bindung ist bereits konfiguriert.

npx wrangler r2 bucket create "$BUCKET" --env-file=.env.management

Listen Sie Ihre Buckets auf und suchen Sie den exakt erzeugten Namen. Andere Buckets gehören zu anderen Arbeiten; lassen Sie sie unverändert.

npx wrangler r2 bucket list --env-file=.env.management

Öffnen Sie im Dashboard Storage & databases → R2 → Overview, wählen Sie genau diesen Bucket aus und prüfen Sie die leere Objektliste. Lassen Sie in seinen Einstellungen die öffentliche Entwicklungs-URL und benutzerdefinierte Domains deaktiviert. Ein Bucket-Name im Dashboard bestätigt die Identität. Die späteren Download-Prüfungen weisen nach, dass die gespeicherten Bytes korrekt sind.

Erstellen Sie einen zweiten Bucket, der diesem Lab gehört. Er stellt eine unabhängige Speichergrenze dar. Verwenden Sie dafür keinen Bucket aus einer anderen Übung. Laden Sie mit der Verwaltungserlaubnis je eine synthetische Datei in beide Buckets:

CONTROL="$NAME-control"
npx wrangler r2 bucket create "$CONTROL" --env-file=.env.management
npx wrangler r2 object put "$BUCKET/documents/report.txt" --remote --file document.txt --content-type text/plain --env-file=.env.management
npx wrangler r2 object put "$CONTROL/retained/handbook.txt" --remote --file retained.txt --content-type text/plain --env-file=.env.management

Lassen Sie den öffentlichen Zugriff für beide Buckets deaktiviert. Im nächsten Schritt erlauben Sie der neuen Berechtigung ausschließlich das Lesen des Dokument-Buckets.

Signaturberechtigung einschränken

In diesem Schritt erstellen Sie eine schreibgeschützte Berechtigung, die auf einen Bucket beschränkt ist. Eine vorsignierte URL kann nicht mehr Zugriffsrechte gewähren als die zum Signieren verwendete Berechtigung. Das Verwaltungstoken kann beide Lab-Buckets verwalten und darf deshalb in dieser Lektion nicht als Signaturidentität verwendet werden.

Die S3-kompatible API ermöglicht Standard-Speicher-SDKs den Zugriff auf R2. Sie verwendet ein separates Zugriffsschlüsselpaar anstelle des Geräte-Tokens von Wrangler. Wählen Sie in R2 Overview Account Details → API Tokens → Manage. Erstellen Sie anschließend ein User API token mit dem Namen der erzeugten Ressource dieses Labs. Wählen Sie Object Read only, beschränken Sie das Token auf genau diesen neuen Bucket und wählen Sie eine kurze Gültigkeitsdauer, falls das Formular dies anbietet. Wählen Sie weder alle Buckets noch den Admin-Zugriff. Lassen Sie die Token-Seite geöffnet, bis Sie das einmalig angezeigte Geheimnis gespeichert haben.

Verwenden Sie die folgenden Bash-Eingabeaufforderungen in der VM. read -s blendet die Eingabe aus; umask 077 macht die Berechtigungsdatei nur für Ihren Benutzer lesbar. Diese Namen sind die standardmäßigen Umgebungsvariablen des AWS SDK. Fügen Sie die Access Key ID und den Secret Access Key in die jeweiligen Eingabeaufforderungen ein und drücken Sie anschließend die Eingabetaste. Fügen Sie nicht den Wert des allgemeinen API-Tokens ein.

umask 077
read -r -s -p 'Access Key ID: ' AWS_ACCESS_KEY_ID; printf '\n'
read -r -s -p 'Secret Access Key: ' AWS_SECRET_ACCESS_KEY; printf '\n'
printf 'AWS_ACCESS_KEY_ID=%s\nAWS_SECRET_ACCESS_KEY=%s\n' "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" > .env.s3
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY

Schreiben Sie einen wiederverwendbaren Standard-SDK-Client. Das SDK benötigt eine Regionszeichenfolge; R2 verwendet auto. Durch das Einlesen der vorhandenen Konfiguration bleiben CLI- und SDK-Operationen auf dasselbe Konto und denselben Bucket gerichtet.

cat > storage.mjs <<'JS'
import { S3Client } from "@aws-sdk/client-s3";
import { readFileSync } from "node:fs";
const config = JSON.parse(readFileSync("wrangler.jsonc", "utf8"));
export const Bucket = config.r2_buckets[0].bucket_name;
export const s3 = new S3Client({
  region: "auto",
  endpoint: `https://${config.account_id}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
  }
});
JS

Wählen Sie ausschließlich den Bucket -docs aus. Lassen Sie den Bucket -control außerhalb des Geltungsbereichs dieses Tokens. Der vorhandene Client in storage.mjs liest .env.s3 nur, wenn --env-file=.env.s3 angegeben ist. Verwenden Sie weder die Admin-Berechtigung noch den Geltungsbereich „alle Buckets“.

Prüfen Sie vor der Weitergabe einer URL den ausgewählten Bucket im Token-Formular. Die echte Anfrage an den Control-Bucket im nächsten Schritt weist unabhängig nach, dass diese Grenze funktioniert.

Schreibgeschütztes Token nur für den Dokument-Bucket

Dieses Beispiel wählt Object Read only und nur den generierten -docs-Bucket aus; der -control-Bucket ist ausgeschlossen. Ihr generierter Name wird abweichen. Die Token-TTL von 24 Stunden ist von der Gültigkeit jeder signierten URL von fünf Minuten oder fünf Sekunden unabhängig. Das Formular zeigt den gewählten Umfang; erfolgreiche und abgelehnte Remote-Anfragen belegen die tatsächlichen Berechtigungen.

Temporäre Downloads signieren und testen

In diesem Schritt signieren Sie GET-Anfragen für ein bestimmtes Objekt und einen bestimmten Zeitraum. Das Signieren erfolgt lokal, ohne R2 zu kontaktieren. Das Erstellen einer URL beweist daher noch keine Berechtigung. R2 prüft die Signatur erst, wenn ein Client die URL verwendet. Jeder, der die URL besitzt, kann die damit erlaubte Operation bis zum Ablauf ausführen. Halten Sie diese Links deshalb aus Protokollen, Nachrichten und Screenshots heraus.

Schreiben Sie ein kleines Signierprogramm. expiresIn wird in Sekunden angegeben. Die Datei speichert eine URL mit einer Gültigkeit von fünf Minuten, eine URL mit einer Gültigkeit von fünf Sekunden und eine absichtlich außerhalb des Geltungsbereichs liegende URL, ohne sie auszugeben:

cat > sign.mjs <<'JS'
import { GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { readFileSync, writeFileSync } from "node:fs";
import { s3, Bucket } from "./storage.mjs";
const config = JSON.parse(readFileSync("wrangler.jsonc", "utf8"));
const command = new GetObjectCommand({ Bucket, Key: "documents/report.txt" });
const allowed = await getSignedUrl(s3, command, { expiresIn: 300 });
const short = await getSignedUrl(s3, command, { expiresIn: 5 });
const outside = await getSignedUrl(s3, new GetObjectCommand({
  Bucket: config.name + "-control", Key: "retained/handbook.txt"
}), { expiresIn: 300 });
const unsigned = new URL(allowed); unsigned.search = "";
writeFileSync("signed.json", JSON.stringify({ allowed, short, outside, unsigned: unsigned.href }), { mode: 0o600 });
console.log("Stored temporary request URLs in private signed.json");
JS
node --env-file=.env.s3 sign.mjs

Verwenden Sie die erlaubte URL umgehend. Diese curl-Anfrage enthält keinen Authorization-Header, da die URL die Signatur trägt. node -p übergibt die gespeicherte URL direkt an curl, ohne sie in der Terminalausgabe anzuzeigen.

curl -fsS "$(node -p "require('./signed.json').allowed")" -o signed-download.txt
cmp document.txt signed-download.txt

Erwarten Sie identische Bytes. Warten Sie nun zehn Sekunden, damit die URL mit fünf Sekunden Gültigkeit abläuft, und prüfen Sie anschließend die Ablehnungsantworten. Diese Anfragen verwenden absichtlich nicht --fail, damit die HTTP-Fehler angezeigt werden:

sleep 10
curl -sS -o expired.xml -w "%{http_code}\n" "$(node -p "require('./signed.json').short")"
curl -sS -o unsigned.xml -w "%{http_code}\n" "$(node -p "require('./signed.json').unsigned")"
curl -sS -o outside.xml -w "%{http_code}\n" "$(node -p "require('./signed.json').outside")"

Erwarten Sie 403 für abgelaufene Anfragen und Anfragen außerhalb des Berechtigungsbereichs. Die unsignierte Anfrage an diesen R2-S3-Endpunkt liefert 400 mit InvalidArgument und der Meldung Authorization: Die erforderlichen Signaturinformationen fehlen. Dies unterscheidet sich davon, gültig signierten Zugangsdaten den Zugriff auf einen anderen Bucket zu verweigern. Prüfen Sie die Fehlernamen, ohne die vollständigen Antwortdokumente auszugeben, da diese Anforderungsdetails enthalten können:

python3 - <<'PYXML'
from xml.etree import ElementTree
for path in ["expired.xml", "unsigned.xml", "outside.xml"]:
    root = ElementTree.parse(path).getroot()
    print(path, root.findtext("Code"))
PYXML

Die abgelaufene Antwort sollte den Ablauf der URL angeben, während der Control-Bucket AccessDenied zurückgibt. Ein Netzwerkfehler ist kein Ergebnis einer Autorisierungsprüfung. Wenn Sie vor dem Test des Control-Buckets mehr als fünf Minuten gebraucht haben, erzeugen Sie die URLs neu, wiederholen Sie die Anfragen an den erlaubten und den außerhalb liegenden Bereich und lassen Sie anschließend die kurze URL erneut ablaufen.

URL-Berechtigung von öffentlichem Zugriff unterscheiden

In diesem Schritt verknüpfen Sie die beobachteten Anfragen mit dem Zugriffsmodell. Der erfolgreiche Link autorisierte einen signierten GET-Aufruf für genau einen Schlüssel. Er aktivierte weder die öffentliche Entwicklungs-URL des Buckets noch autorisierte er PUT oder meldete einen Benutzer bei Ihrer Anwendung an.

Öffnen Sie im Dashboard die Einstellungen beider diesem Lab gehörenden Buckets. Lassen Sie öffentliche Entwicklungs-URLs deaktiviert und fügen Sie keine benutzerdefinierten Domains hinzu. Prüfen Sie auf der Seite des Objekttokens, dass das schreibgeschützte Token ausschließlich den Bucket -docs umfasst. Zeigen Sie das einmalig angezeigte Geheimnis nicht in einem Screenshot.

Führen Sie jetzt die Plattformprüfung aus. Sie erzeugt eigene signierte Anfragen, verlangt exakt die erlaubten Bytes und prüft die Ablehnungen für unsignierte, abgelaufene und außerhalb des Geltungsbereichs liegende Anfragen. Dies ist ein echter Nachweis über die Remote-API. Die gespeicherte Datei signed.json ist kein Abschlussmarker.

Entscheiden Sie in einer Produktionsanwendung, ob ein Benutzer auf das Dokument zugreifen darf, bevor Sie einen signierten Link ausstellen. Nach der Ausstellung kann der Bearer-Link kopiert werden. Das spätere Lab zur Anwendungsautorisierung behandelt diese Entscheidung direkt. Signierte S3-URLs richten sich an den R2-S3-Endpunkt des Kontos, nicht an eine öffentliche r2.dev-Adresse oder eine benutzerdefinierte Domain.

Beide Lab-Buckets bereinigen

In diesem Schritt entfernen Sie zunächst die beiden ausdrücklich angelegten Fixture-Schlüssel und anschließend deren Buckets. Lassen Sie die Verwaltungsberechtigung aktiv, bis die Plattform bestätigt, dass beide Bucket-Namen nicht mehr vorhanden sind.

BUCKET=$(node -p "JSON.parse(require('fs').readFileSync('wrangler.jsonc')).r2_buckets[0].bucket_name")
CONTROL=$(node -p "JSON.parse(require('fs').readFileSync('wrangler.jsonc')).name + '-control'")
npx wrangler r2 object delete "$BUCKET/documents/report.txt" --remote --env-file=.env.management
npx wrangler r2 object delete "$CONTROL/retained/handbook.txt" --remote --env-file=.env.management
npx wrangler r2 bucket delete "$BUCKET" --env-file=.env.management
npx wrangler r2 bucket delete "$CONTROL" --env-file=.env.management
npx wrangler r2 bucket list --env-file=.env.management

Bestätigen Sie bei der entsprechenden Eingabe jeden exakten Namen. Eine erfolgreiche Bucket-Liste darf beide Namen nicht enthalten. Löschen Sie niemals einen anderen Bucket, nur um die globale Liste zu leeren.

Laborkenntnis widerrufen und abmelden

In diesem Schritt schließen Sie den durch diese Übung hinterlassenen Zugriff. Widerrufen Sie auf der Seite R2 API Tokens ausschließlich das für dieses Lab benannte Objekttoken. Widerrufen Sie auf der API-Token-Seite Ihres Profils das separate R2-Verwaltungstoken, das Sie für dieses Lab erstellt haben. Das Löschen eines Buckets widerruft kein Token, und die Abmeldung von Wrangler widerruft keine S3-Anmeldedaten.

Entfernen Sie nach dem Widerruf die lokale Berechtigungsdatei und melden Sie diese VM ab:

rm .env.s3 .env.management signed.json
npx wrangler logout

Prüfen Sie die strukturierte Identität. Der Status ungleich null ist im abgemeldeten Zustand zu erwarten:

npx wrangler whoami --json || true

Erwarten Sie loggedIn: false. Lassen Sie Ihre gewöhnliche Dashboard-Anmeldung bestehen. Die Plattform prüft das Entfernen der lokalen Berechtigungsdateien und die Abmeldung von Wrangler. Beide Token-Widerrufe sind in diesem Kandidaten manuelle Dashboard-Prüfpunkte; sie werden nicht aus dem Löschen der Dateien abgeleitet.

Zusammenfassung

Erstellen Sie einen eingeschränkten Zugriff auf private Dateien, weisen Sie den Erfolg und die Grenzen vorsignierter Zugriffe nach, unterscheiden Sie öffentlichen Zugriff von Autorisierung und widerrufen Sie die Laborkenntnisse.