Übung: Schützen von Webhooknutzlasten mit einem Geheimnis
In dieser Übung lernen Sie, wie Sie Ihre Webhooknutzdaten mit einem Geheimnis schützen und wie Sie mithilfe Ihrer Azure-Funktion überprüfen, ob Nutzdaten von GitHub stammen.
Abrufen eines Schlüssels für Ihre Azure-Funktion
Kehren Sie im Azure-Portal zu der Funktions-App zurück, die Sie in der ersten Übung dieses Moduls erstellt haben.
Wählen Sie im linken Menübereich unter Funktionen die Option Funktionen aus. Der Bereich Funktionen wird für Ihre Funktions-App angezeigt.
Wählen Sie die erstellte Funktion „HttpTrigger1“ aus. Der Bereich HttpTrigger1 wird für Ihre Funktion angezeigt.
Klicken Sie auf der linken Seite des Menübereichs unter Developer (Entwickler) auf Programmieren und testen. Der Bereich Programmieren und testen wird für Ihre Funktion angezeigt.
Fügen Sie in der JavaScript-Datei index.js Ihrer Funktion einen Verweis auf die crypto-js-Bibliothek am Anfang der Datei über der
module.exports
-Anweisung hinzu.const Crypto = require('crypto');
Klicken Sie in der oberen Menüleiste auf Speichern. Dann wird der Bereich Protokolle unten angezeigt.
Klicken Sie auf der linken Seite des Menübereichs unter Entwickler auf Funktionsschlüssel. Der Bereich Funktionsschlüssel wird für Ihre Funktion geöffnet.
Wählen Sie unter der Spalte Wert den Link Wert anzeigen aus.
Wählen Sie das Symbol In Zwischenablage kopieren aus, und speichern Sie diesen Schlüssel für die Verwendung im nächsten Schritt.
Klicken Sie auf der linken Seite des Menübereichs unter Developer (Entwickler) auf Programmieren und testen. Der Bereich Programmieren und testen wird für Ihre Funktion angezeigt.
Fügen Sie im Codeblock nach der Anweisung
context.log
den folgenden Code hinzu. Ersetzen Sie <Standardschlüssel> durch den Standardschlüssel, den Sie zuvor in die Zwischenablage kopiert haben:const hmac = Crypto.createHmac("sha1", "<default key>"); const signature = hmac.update(JSON.stringify(req.body)).digest('hex');
Dieser Code berechnet den Hash des Schlüssels mithilfe des gleichen Mechanismus wie GitHub.
Fügen Sie einen weiteren
const
am Anfang des Schlüssels ein, der demsha1=
vorangestellt ist, sodass er dem Format desx-hub-signature
im Anforderungsheader entspricht. Fügen Sie Ihrer Funktion den folgenden Code hinzu:const shaSignature = `sha1=${signature}`;
Fügen Sie den folgenden Code zum Abrufen der GitHub-Signatur aus dem Anforderungsheader hinzu:
const gitHubSignature = req.headers['x-hub-signature'];
Vergleichen Sie die beiden Zeichenfolgen. Verarbeiten Sie die Anforderung wie folgt, wenn diese übereinstimmen:
if (!shaSignature.localeCompare(gitHubSignature)) { // Existing code if (req.body.pages[0].title) { ... } else { ... } }
Geben Sie dem Sender die Antwort „HTTP 401 (Nicht autorisiert)“ mit der Nachricht zurück, dass die Signaturen nicht übereinstimmen, wenn die Zeichenfolgen nicht übereinstimmen.
if (!shaSignature.localeCompare(gitHubSignature)) { ... } else { context.res = { status: 401, body: "Signatures don't match" }; }
Die vollständige Funktion sollte wie folgt aussehen:
const Crypto = require('crypto'); module.exports = async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); const hmac = Crypto.createHmac("sha1", "<default key>"); const signature = hmac.update(JSON.stringify(req.body)).digest('hex'); const shaSignature = `sha1=${signature}`; const gitHubSignature = req.headers['x-hub-signature']; if (!shaSignature.localeCompare(gitHubSignature)) { if (req.body.pages[0].title) { context.res = { body: "Page is " + req.body.pages[0].title + ", Action is " + req.body.pages[0].action + ", Event Type is " + req.headers['x-github-event'] }; } else { context.res = { status: 400, body: ("Invalid payload for Wiki event") } } } else { context.res = { status: 401, body: "Signatures don't match" }; } };
Klicken Sie in der oberen Menüleiste auf Speichern. Der Bereich Protokolle wird mit der Anweisung Verbunden! angezeigt.
Aktualisieren des Webhookgeheimnisses
Wechseln Sie zu Ihrem GitHub-Konto im GitHub-Portal.
Wählen Sie Ihr Repository aus.
Wählen Sie in der oberen Menüleiste Einstellungen aus. Der Bereich Einstellungen wird angezeigt.
Klicken Sie in der Randleiste auf die Option Webhooks. Der Bereich Webhooks wird angezeigt.
Wählen Sie neben Ihrem Webhook Bearbeiten aus.
Geben Sie im Textfeld Geheimnis den Standardschlüssel aus Ihrer Funktion ein, den Sie zuvor in dieser Übung gespeichert haben.
Scrollen Sie zum Ende der Seite, und wählen Sie Webhook aktualisieren aus. Der Bereich Webhooks > Webhooks verwalten wird angezeigt.
Testen des Webhooks und der Azure-Funktion
Wählen Sie die Registerkarte Aktuelle Lieferungen aus.
Wählen Sie den neuesten (obersten) Übermittlungseintrag aus, indem Sie dessen Schaltfläche mit den Auslassungspunkten (...) auswählen.
Wählen Sieerneut übermitteln aus. Wählen Sie im angezeigten Dialogfeld Redeliver payload? (Nutzdaten erneut übermitteln?) die Option Yes, redeliver this payload (Ja, Nutzdaten übermitteln) aus.
Dadurch wird simuliert, dass Sie Ihre Wikiseite erneut bearbeiten.
Wählen Sie den neuesten (obersten) Übermittlungseintrag aus, indem Sie dessen Schaltfläche mit den Auslassungspunkten (...) auswählen.
Im Abschnitt Header wird
x-hub-signature
angezeigt. Sie werden auch feststellen, dass der Antwortcode 200 lautet und angibt, dass die Anforderung erfolgreich verarbeitet wurde.Request URL: https://testwh123456.azurewebsites.net/api/HttpTrigger1?code=aUjXIpqdJ0ZHPQuB0SzFegxGJu0nAXmsQBnmkCpJ6RYxleRaoxJ8cQ%3D%3D Request method: POST content-type: application/json Expect: User-Agent: GitHub-Hookshot/16496cb X-GitHub-Delivery: ce122460-6aae-11e9-99d4-de6a298a424a X-GitHub-Event: gollum X-Hub-Signature: sha1=<hash of default key>
Testen einer ungültigen Signatur
Wählen Sie im GitHub-Portal auf der Seite „Webhooks“ die Registerkarte Einstellungen aus.
Wählen Sie im Testfeld Secret (Geheimnis) die Option Change Secret (Geheimnis ändern) aus.
Geben Sie eine zufällige Zeichenfolge ein, scrollen Sie nach unten, und wählen Sie dann Update Webhook (Webhook aktualisieren) aus.
Der vom Webhook verwendete Schlüssel sollte nicht mehr mit dem von der Azure-Funktion erwarteten Schlüssel übereinstimmen.
Wählen Sie die Registerkarte Aktuelle Lieferungen aus.
Wählen Sie den neuesten (obersten) Übermittlungseintrag aus, indem Sie dessen Schaltfläche mit den Auslassungspunkten (...) auswählen.
Wählen Sie Redeliver (Erneut übermitteln) und dann im angezeigten Dialogfeld Redeliver payload? (Nutzdaten erneut übermitteln?) die Option Yes, redeliver this payload (Ja, Nutzdaten übermitteln) aus.
Dieses Mal werden Sie feststellen, dass der Antwortcode 401 lautet und angibt, dass die Anforderung nicht autorisiert wurde.
Wählen Sie den neuesten (obersten) Übermittlungseintrag (redelivery) aus, indem Sie dessen Schaltfläche mit den Auslassungspunkten (...) auswählen.
Wählen Sie die Registerkarte Response aus, und vergewissern sich, dass im Abschnitt Body (Text) die Meldung „Signatures don't match“ (Die Signaturen stimmen nicht überein) angezeigt wird.