Могу ли я получить согласованное значение "iss" для идентификатора Google OpenIDConnect id_token?
Я использую аутентификацию OpenIDConnect от Google и хочу проверить JWT id_token
вернулся из Google. Тем не менее, документация не соответствует тому, какое значение Google возвращает для iss
(эмитент) претензия в идентификационном токене.
На одной странице написано: "iss: всегда accounts.google.com", а на другой странице указано "значение iss в токене идентификатора равно accounts.google.com
или же https://accounts.google.com
"и комментарий в примере кода дополнительно объясняет:
// If you retrieved the token on Android using the Play Services 8.3 API or newer, set
// the issuer to "https://accounts.google.com". Otherwise, set the issuer to
// "accounts.google.com". If you need to verify tokens from multiple sources, build
// a GoogleIdTokenVerifier for each issuer and try them both.
У меня есть приложение на стороне сервера, а не приложение для Android, поэтому я не использую Play Services.
Чтобы еще больше мутить воду, сама спецификация OpenIDConnect содержит примечание, которое:
Разработчики могут пожелать знать, что на момент написания этой статьи развернутые Google реализации OpenID Connect выдают токены идентификаторов, в которых отсутствует обязательный префикс схемы https: // в значении претензии iss (эмитента). Поэтому реализации проверяющей стороны, желающие работать с Google, должны иметь код для обхода этого до тех пор, пока их реализация не будет обновлена. Любой такой обходной код должен быть написан таким образом, чтобы в этот момент он не ломался. Google добавляет отсутствующий префикс к значениям их эмитента.
Этот документ датирован 8 ноября 2014 года. С тех пор Google стандартизировал iss
значение, или мне действительно нужно проверить их обоих? Комментарий выше, кажется, указывает, что только Play Services >=8.3 получает iss
с https://
и везде значение будет просто accounts.google.com
, Это правда?
2 ответа
Вы должны проверить обе возможности. Это то, что сработало для меня...
Расшифруйте токен, чтобы получить эмитента. Если эмитент не равен ни одному из https://accounts.google.com
или же accounts.google.com
Вы можете остановиться там. Это неверный токен.
Если эмитент равен какой-либо из приведенных выше строк Google, передайте это же декодированное значение эмитента на этап проверки.
Ниже приведена реализация, которую я написал в JavaScript для некоторого промежуточного программного обеспечения Node.js Express:
function authorize(req, res, next) {
try {
var token = req.headers.authorization;
var decoded = jwt.decode(token, { complete: true });
var keyID = decoded.header.kid;
var algorithm = decoded.header.alg;
var pem = getPem(keyID);
var iss = decoded.payload.iss;
if (iss === 'accounts.google.com' || iss === 'https://accounts.google.com') {
var options = {
audience: CLIENT_ID,
issuer: iss,
algorithms: [algorithm]
}
jwt.verify(token, pem, options, function(err) {
if (err) {
res.writeHead(401);
res.end();
} else {
next();
}
});
} else {
res.writeHead(401);
res.end();
}
} catch (err) {
res.writeHead(401);
res.end();
}
}
Обратите внимание, что эта функция использует jsonwebtoken
а также jwk-to-pem
узловые модули. Я опустил детали getPem
функция, которая в конечном итоге преобразует веб-ключ json в формат pem.
Для начала, я определенно согласен с тем, что документация Google - мрачный бизнес.
Существует несколько способов проверить целостность идентификатора токена на стороне сервера (кстати, это страница, которую вы ищете):
- "Вручную" - постоянно загружать открытые ключи Google, проверять подпись, а затем каждое поле, включая
iss
один; главное преимущество (хотя и небольшое, на мой взгляд), которое я вижу здесь, заключается в том, что вы можете минимизировать количество запросов, отправляемых в Google). - "Автоматически" - сделать GET на конечной точке Google, чтобы проверить этот токен - безусловно, самое простое:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
- Использование клиентской библиотеки Google API - накладные расходы могут не стоить того,
C#
не имеет официального и т. д.
Я предлагаю вам перейти ко второму варианту и позволить Google беспокоиться об алгоритме проверки.