我正在使用Google's OpenIDConnect authentication,我想验证从Google返回的JWT id_token
。但是,文档似乎与Google在ID令牌中为iss
(发行人)声明返回的价值不一致。
One page说,“发布:始终为accounts.google.com”,但another page说“ID令牌中的iss值等于{{1 }}或accounts.google.com
“以及示例代码中的注释进一步说明:
https://accounts.google.com
我有一个服务器端应用程序,而不是Android应用程序,所以我没有使用Play服务。
为了使水更加泥泞,the OpenIDConnect specification itself包含一条说明:
实施者可能希望了解到,截至撰写本文时,Google部署的OpenID Connect实施会发出ID标记,这些标记会从iss(颁发者)声明值中省略所需的https://方案前缀。因此,希望与Google合作的依赖方实施需要有代码来解决这个问题,直到实施更新为止。任何此类变通方法代码都应以不会破坏的方式编写,Google会将缺少的前缀添加到其颁发者值中。
该文件的日期是2014年11月8日。从那时起,谷歌标准化// 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.
值,还是我真的需要检查它们?上面的评论似乎表明只有Play服务> = 8.3获得iss
iss
,其他任何地方的价值都只是https://
。这是真的吗?
答案 0 :(得分:0)
首先,我绝对同意Google的文档是一个模糊的业务。
您可以通过几种不同的方式验证服务器端ID令牌的完整性(btw this是您要查找的页面):
iss
个字段;主要优势(虽然我认为是一个小优势)我在这里看到的是,您可以最大限度地减少发送给Google的请求数量。https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
C#
没有正式的等等。我建议你选择第二个选项,让Google担心验证算法。
答案 1 :(得分:0)
你必须检查两种可能性。这对我有用......
解码令牌以获取发行者。如果发行人不等于tensorflow_model_server
或https://accounts.google.com
中的任何一个,您可以在那里停止。这是一个无效的令牌。
如果发行人等于上述任一Google字符串,则将相同的已解码发行人值传递给验证步骤。
以下是我在JavaScript中为一些Node.js Express中间件编写的实现:
accounts.google.com
请注意,此函数使用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
函数的细节,该函数最终将json Web密钥转换为pem格式。