Вот как, например, интегрировать аутентификацию Azure AD с REST API Node.js. В частности, вот подробности о проверке токена носителя JWT, созданного с помощью Azure AD.

TL;DR

  • git clone или скачайте мой проект на GitHub здесь
  • В index.js вставьте строку токена на предъявителя (Base64, без префикса Bearer) в переменную token
  • Вставьте строку сертификата X.509 открытого ключа (без префикса / суффикса PEM) в переменную x5cString
  • Запустите npm install, а затем node . из командной строки

Если ваш токен распечатан на консоли, значит, проверка прошла успешно. В противном случае появится сообщение об ошибке.

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

Задний план

Допустим, у вас есть конечная точка API, использующая Node.js (Express, LoopBack, Feathers и т. Д.), И вы хотите принять токены носителя JWT, выпущенные Azure AD. Это потрясающий способ без сохранения состояния для единого входа (SSO), скажем, между Microsoft Office 365 или SharePoint и вашим собственным настраиваемым одностраничным приложением (SPA).

Вы найдете несколько хороших примеров использования ADAL в браузере для получения токена носителя, подписанного Microsoft Azure AD.

Однако, возможно, не так ясно, как проверить или проверить токен-носитель на стороне Node.js в вашем коде API. В этой небольшой статье блога «покажи и расскажи» описывается «трюк», необходимый для выполнения проверки токена носителя JWT.

Старт в кроличью нору

Я сразу скажу, что Microsoft, похоже, усложняет все это дело, чем должно быть. Я начал с чтения этой статьи, в которой мне предлагается изучить этот онлайн-документ JSON, содержащий значение "jwks_uri", указывающее на этот URI, где хранятся фактические открытые ключи.

Открытые ключи также предоставляются в формате JSON, и вы должны сделать перекрестные ссылки на них, чтобы предположительно найти правильный для вашей конкретной аренды Office 365.

Позвольте мне объяснить, что я имею в виду под «перекрестной ссылкой». Вот как выглядит файл JSON с открытыми ключами. Обратите внимание, что в массиве данных открытого ключа (на момент написания) есть 3 элемента (объекта).

{ "keys": [
  { "kty":"RSA",
    "use":"sig",
    "kid":"z44wMdHu8wKsumrbfaK98qxs5YI",
    "x5t":"z44wMdHu8wKsumrbfaK98qxs5YI",
    "n":"p3HhMQsqmgSjeiDsZ1ay...",
    "e":"AQAB",
    "x5c": ["MIIDBTCCAe2gAwIBAgIQaD0..."]
  },
  { "kty":"RSA",
    "use":"sig",
    "kid":"SSQdhI1cKvhQEDSJxE2gGYs40Q0",
    "x5t":"SSQdhI1cKvhQEDSJxE2gGYs40Q0",
    "n":"pJUB90EMxiNjgkVz5CLL...",
    "e":"AQAB",
    "x5c":["MIIDBTCCAe2gAwIBAgIQHJ7yHxN..."]
  },
  { "kty":"RSA",
    "use":"sig",
    "kid":"2S4SCVGs8Sg9LS6AqLIq6DpW-g8",
    "x5t":"2S4SCVGs8Sg9LS6AqLIq6DpW-g8",
    "n":"oZ-QQrNuB4ei9ATYrT61ebPt...",
    "e":"AQAB",
    "x5c":["MIIDKDCCAhCgAwIBAgIQBH..."]
  }
]}

Основным индексом объектов в массиве является значение "x5t" (предположительно X.509 'Tag'):

  • z44wMdHu8wKsumrbfaK98qxs5YI,
  • SSQdhI1cKvhQEDSJxE2gGYs40Q0, or
  • 2S4SCVGs8Sg9LS6AqLIq6DpW-g8

Следуя так далеко? Здорово.

Перекрестная ссылка на токен, выпущенный Azure AD, чтобы получить правильный открытый ключ

Чтобы определить, с каким открытым ключом может быть проверен ваш конкретный токен на предъявителя, проверьте соответствующее значение "x5t" в разделе заголовок вашего токена на предъявителя.

Затем из соответствующего объекта в массиве keys (показанном выше и, как упоминалось выше, доступном здесь), возьмите значение "x5c", чтобы создать свой фактический открытый ключ для целей проверки токена.

Создайте открытый ключ

Теперь, когда у вас есть правильная строка "x5c", вы почти готовы проверить свой токен на предъявителя! Вау, правда?

Уловка на этом последнем шаге состоит в том, чтобы заметить, что строка "x5c", как следует из метки, является Сертификатом X.509.

Следовательно, чтобы успешно использовать эту "x5c" строку в качестве аргумента открытого ключа для вызова проверки токена JWT, вам необходимо выполнить небольшую конкатенацию строк, чтобы преобразовать ее в ожидаемый формат PEM (см. Также здесь).

var token = '...';
var x5cString = '...';
var publicKey = '-----BEGIN CERTIFICATE-----\n' + x5cString + '\n-----END CERTIFICATE-----';
...
// Verify
verifiedToken = jwt.verify(token, publicKey);

Первоначально опубликовано на stevelathrop.net 5 февраля 2018 г.