Ćwiczenie – zabezpieczanie ładunków elementu webhook za pomocą wpisu tajnego
W tym ćwiczeniu będziesz chronić ładunek elementu webhook przy użyciu wpisu tajnego i dowiesz się, jak sprawdzić, czy ładunki są rzeczywiście z usługi GitHub przy użyciu funkcji platformy Azure.
Uzyskiwanie klucza dla funkcji platformy Azure
W witrynie Azure Portal wróć do aplikacji funkcji utworzonej w pierwszym ćwiczeniu w module.
W okienku menu po lewej stronie w obszarze Funkcje wybierz pozycję Funkcje. Okienko Funkcje zostanie wyświetlone dla aplikacji funkcji.
Wybierz utworzony element HttpTrigger1. Zostanie wyświetlone okienko HtttpTrigger1 dla funkcji.
W okienku menu po lewej stronie w obszarze Deweloper wybierz pozycję Kod i testowanie. Zostanie wyświetlone okienko Kod i test dla funkcji.
W pliku JavaScript index.js funkcji dodaj odwołanie do biblioteki crypto-js na początku pliku, nad instrukcją
module.exports
.const Crypto = require('crypto');
Na górnym pasku menu wybierz pozycję Zapisz. Okienko Dzienniki zostanie wyświetlone w dolnej części okienka.
W okienku menu po lewej stronie w obszarze Deweloper wybierz pozycję Klucze funkcji. Zostanie wyświetlone okienko Klucze funkcji dla funkcji.
W kolumnie Wartość wybierz link Pokaż wartość .
Wybierz ikonę Kopiuj do schowka i zapisz ten klucz do użycia w następnym kroku.
W okienku menu po lewej stronie w obszarze Deweloper wybierz pozycję Kod i testowanie. Zostanie wyświetlone okienko Kod i test dla funkcji.
W bloku kodu po instrukcji
context.log
dodaj następujący kod. Zastąp <klucz> domyślny kluczem domyślnym skopiowany właśnie do schowka:const hmac = Crypto.createHmac("sha1", "<default key>"); const signature = hmac.update(JSON.stringify(req.body)).digest('hex');
Ten kod oblicza skrót klucza, korzystając z tego samego mechanizmu co usługa GitHub.
Dodaj kolejny
const
element, który poprzedzasha1=
początek klucza, tak aby był zgodny z formatemx-hub-signature
w nagłówku żądania. Dodaj następujący kod do funkcji.const shaSignature = `sha1=${signature}`;
Dodaj następujący kod, aby pobrać sygnaturę usługi GitHub z nagłówka żądania:
const gitHubSignature = req.headers['x-hub-signature'];
Porównaj dwa ciągi. Jeśli są zgodne, przetwórz żądanie w następujący sposób:
if (!shaSignature.localeCompare(gitHubSignature)) { // Existing code if (req.body.pages[0].title) { ... } else { ... } }
Jeśli ciągi są różne, zwróć odpowiedź HTTP 401 (brak autoryzacji) z komunikatem do nadawcy informującym o tym, że sygnatury nie są zgodne.
if (!shaSignature.localeCompare(gitHubSignature)) { ... } else { context.res = { status: 401, body: "Signatures don't match" }; }
Ukończona funkcja powinna wyglądać następująco:
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" }; } };
Na górnym pasku menu wybierz pozycję Zapisz. Zostanie wyświetlone okienko Dzienniki z instrukcją Connected! .
Aktualizacja wpisu tajnego elementu webhook
Przełącz się na konto usługi GitHub w portalu usługi GitHub.
Wybierz repozytorium.
Na górnym pasku menu wybierz pozycję Ustawienia. Zostanie wyświetlone okienko Ustawienia .
Na pasku bocznym wybierz pozycję Elementy webhook. Zostanie wyświetlone okienko Elementy webhook .
Wybierz pozycję Edytuj obok elementu webhook.
W polu tekstowym Wpis tajny wprowadź klucz domyślny z funkcji, która wcześniej zapisana w tym ćwiczeniu.
Przewiń w dół do dołu strony i wybierz pozycję Aktualizuj element webhook. Zostanie wyświetlone okienko Elementy webhook/Zarządzanie elementami webhook.
Testowanie elementu webhook i funkcji platformy Azure
Wybierz kartę Ostatnie dostawy .
Wybierz najnowszy (górny) wpis dostarczania, wybierając przycisk wielokropka (...).
Wybierz pozycję Dostarcz ponownie. W wyświetlonym oknie dialogowym Ponowne pobieranie ładunku? wybierz pozycję Tak, ponownie określ ten ładunek.
Ta akcja symuluje ponowne edytowanie strony typu wiki.
Wybierz najnowszy (górny) wpis dostarczania, wybierając przycisk wielokropka (...).
W sekcji Nagłówki zobaczysz element
x-hub-signature
. Zobaczysz również, że kod odpowiedzi to 200, co wskazuje na pomyślne przetworzenie żądania.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>
Testowanie nieprawidłowej sygnatury
W portalu GitHub na stronie elementów webhook wybierz kartę Ustawienia .
W polu Test wpisu tajnego wybierz pozycję Zmień wpis tajny.
Wprowadź losowy ciąg, przewiń ekran w dół, a następnie wybierz pozycję Zaktualizuj element webhook.
Klucz używany przez element webhook nie powinien już pasować do klucza oczekiwanego przez funkcję platformy Azure.
Wybierz kartę Ostatnie dostawy .
Wybierz najnowszy (górny) wpis dostarczania, wybierając przycisk wielokropka (...).
Wybierz pozycję Redeliver (Redeliver), a następnie w wyświetlonym oknie dialogowym Ponowne pobieranie ładunku wybierz pozycję Tak, ponownie dostarcz ten ładunek.
Tym razem zobaczysz, że kod odpowiedzi to 401, co wskazuje brak autoryzacji żądania.
Wybierz najnowszy (górny) wpis dostarczania (redelivery), wybierając przycisk wielokropka (...).
Wybierz kartę Odpowiedź , a następnie w sekcji Treść sprawdź, czy zostanie wyświetlony komunikat "Podpisy nie są zgodne".