Упражнение. Защита полезных данных веб-перехватчика с помощью секрета

Завершено

В этом упражнении вы защитите полезные данные веб-перехватчика с помощью секрета и узнаете, как проверить, что полезные данные фактически находятся из GitHub с помощью функции Azure.

Получение ключа для функции Azure

  1. В портал Azure вернитесь в приложение-функцию, созданное в первом упражнении в модуле.

  2. В меню слева в разделе Функции выберите Функции. Появится панель Функции вашего приложения-функции.

  3. Выберите созданный вами триггер HttpTrigger1. Для функции отобразится панель HtttpTrigger1.

  4. В меню навигации слева в разделе Разработчик выберите Код и тестирование. Для функции отобразится панель Код и тестирование.

  5. В файле JavaScript index.js добавьте ссылку на библиотеку crypto-js в начале файла над оператором module.exports.

    const Crypto = require('crypto');
    
  6. В верхней строке меню выберите Сохранить. Откроется панель Журналы в нижней части панели.

  7. В меню слева в разделе Разработчик выберите Функциональные клавиши. Появится панель Функциональные клавиши вашей функции.

  8. В столбце "Значение" выберите ссылку "Показать значение".

  9. Выберите значок Копировать в буфер обмена и сохраните этот ключ для использования на следующем шаге.

  10. В меню навигации слева в разделе Разработчик выберите Код и тестирование. Для функции отобразится панель Код и тестирование.

  11. Добавьте следующий код в блок кода после инструкции context.log. Замените <ключ по умолчанию> ключом по умолчанию, скопированным в буфер обмена ранее:

    const hmac = Crypto.createHmac("sha1", "<default key>");
    const signature = hmac.update(JSON.stringify(req.body)).digest('hex');
    

    Этот код вычисляет хэш ключа с помощью того же механизма, что и GitHub.

  12. Добавьте еще const перед sha1= в начало ключа, чтобы он соответствовал формату x-hub-signature в заголовке запроса. Добавьте в функцию следующий код.

    const shaSignature = `sha1=${signature}`;
    
  13. Добавьте следующий код для получения подписи GitHub из заголовка запроса:

    const gitHubSignature = req.headers['x-hub-signature'];
    
  14. Сравните эти две строки. Если они совпадают, обработайте запрос следующим образом:

    if (!shaSignature.localeCompare(gitHubSignature)) {
        // Existing code
        if (req.body.pages[0].title) {
            ...
        }
        else {
            ...
        }
    }
    
  15. Если строки не совпадают, возвратите ответ HTTP 401 (не санкционировано) в сообщении отправителю о том, что подписи не совпадают.

    if (!shaSignature.localeCompare(gitHubSignature))
    {
        ...
    }
    else {
        context.res = {
            status: 401,
            body: "Signatures don't match"
        };
    }
    
    

    Готовая функция будет выглядеть так:

    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"
            };
        }
    };
    
  16. В верхней строке меню выберите Сохранить. Появится панель Журналы с сообщением Подключено!.

Обновление секрета веб-перехватчика

  1. Перейдите к учетной записи GitHub на портале GitHub.

  2. Выберите репозиторий.

  3. В верхней строке меню выберите Параметры. Появится панель Настройки.

  4. На боковой панели выберите Веб-перехватчики. Отобразится панель Веб-перехватчики.

  5. Щелкните Изменить рядом с веб-перехватчиком.

  6. В текстовом поле Секрет введите ключ по умолчанию из функции, сохраненный ранее в этом упражнении.

  7. В нижней части страницы щелкните Обновить веб-перехватчик. Появится панель Веб-перехватчики/Управление веб-перехватчиком.

Тестирование веб-перехватчика и функции Azure

  1. Перейдите на вкладку Последние доставки.

  2. Выберите последнюю (верхнюю) запись доставки, нажав кнопку с многоточием (...).

  3. Щелкните Redeliver (Повторно доставить). В появившемся диалоговом окне Доставлять полезные данные повторно? щелкните Да, повторно доставить эти полезные данные.

    Это действие имитирует редактирование вики-страницы еще раз.

  4. Выберите последнюю (верхнюю) запись доставки, нажав кнопку с многоточием (...).

  5. В разделе Заголовки вы увидите x-hub-signature. Вы также увидите, что код ответа — 200, что указывает на то, что запрос обработан успешно.

    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>
    

Тестирование недопустимой подписи

  1. На портале GitHub на странице "Веб-перехватчики" перейдите на вкладку Параметры.

  2. В поле Секрет выберите Изменить секрет.

  3. Введите произвольную строку, прокрутите содержимое вниз и щелкните Обновить веб-перехватчик.

    Ключ, используемый веб-перехватчиком, больше не должен совпадать с ключом, ожидаемым функцией Azure.

  4. Перейдите на вкладку Последние доставки.

  5. Выберите последнюю (верхнюю) запись доставки, нажав кнопку с многоточием (...).

  6. Выберите Доставить повторно и в появившемся диалоговом окне Доставлять полезные данные повторно? щелкните Да, повторно доставить эти полезные данные.

  7. На этот раз вы увидите, что код ответа — 401. Это указывает на то, что запрос не авторизован.

  8. Выберите последнюю (верхнюю) запись доставки (повторная доставка), нажав кнопку с многоточием (...).

  9. Перейдите на вкладку Ответ и убедитесь в том, что сообщение "Подписи не совпадают" отображается в разделе Текст.