我可以为Google OpenIDConnect id_token获得一致的'iss'值吗?

时间:2016-07-27 16:43:50

标签: google-oauth google-authentication google-oauth2 google-openid google-openidconnect

我正在使用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://。这是真的吗?

2 个答案:

答案 0 :(得分:0)

首先,我绝对同意Google的文档是一个模糊的业务。

您可以通过几种不同的方式验证服务器端ID令牌的完整性(btw this是您要查找的页面):

  1. “手动” - 不断下载Google的公钥,验证签名,然后检查每个字段,包括iss个字段;主要优势(虽然我认为是一个小优势)我在这里看到的是,您可以最大限度地减少发送给Google的请求数量。
  2. “自动” - 在Google端点上执行GET以验证此令牌 - 到目前为止最简单: https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
  3. 使用Google API客户端库 - 开销可能不值得,C#没有正式的等等。
  4. 我建议你选择第二个选项,让Google担心验证算法。

答案 1 :(得分:0)

你必须检查两种可能性。这对我有用......

解码令牌以获取发行者。如果发行人不等于tensorflow_model_serverhttps://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格式。