Google的OpenIDConnect返回无法解析的Base64令牌

时间:2015-02-16 19:28:26

标签: .net json.net base64 dotnet-httpclient openid-connect

作为了解OpenIDConnect的练习,我正在尝试authenticate in my web app with Google following this guide

问题是我无法读取Google发送到我的应用程序的令牌>

var bytes = Convert.FromBase64String(codeEx.Id_token);
var token = Encoding.ASCII.GetString(bytes);

它在第一行中失败说:“输入不是有效的Base-64字符串,因为它包含非基本64字符,两个以上的填充字符或填充字符中的非法字符。”

doc指出:“ID令牌是以base 64编码的加密签名的JSON对象。”

由于显而易见的原因,我不能把令牌放在这里。我试过了:

我得到了代码交换响应,并使用NewtonSoft.Json库对其进行反序列化:

  var http = new HttpClient(handler);
  HttpResponseMessage result = await http.PostAsync("https://www.googleapis.com/oauth2/v3/token", postData);
  var json = JObject.Parse(await result.Content.ReadAsStringAsync());

  if (json.Property("error") != null)
      throw new Exception(json.Property("error").Value.ToString() + ":" + json.Property("error_description").Value.ToString());

  var codeEx = json.ToObject<CodeExchangeResponse>();

我不知道编码是否存在任何潜在问题。我可以在令牌中看到几个' - '和'_'。

关于如何阅读令牌的任何想法?

2 个答案:

答案 0 :(得分:4)

来自this post

  

“id_token”以称为JSON Web Token(JWT)的格式编码。 JWT是   “标题”,“正文”,“签名”与句点(。)的串联。

因此,您需要在id_token上拆分.并仅解码第二段:

var http = new HttpClient(handler);
var result = await http.PostAsync("https://www.googleapis.com/oauth2/v3/token", postData);
var json = JObject.Parse(await result.Content.ReadAsStringAsync());
var token = Convert.FromBase64String(json.id_token.split('.')[1]);

答案 1 :(得分:1)

在对令牌的紧凑表示进行反序列化后,使用base64url解码(而不是普通base64),如下所示:

var http = new HttpClient(handler);
var result = await http.PostAsync("https://www.googleapis.com/oauth2/v3/token", postData);
var json = JObject.Parse(await result.Content.ReadAsStringAsync());
var payload = json.id_token.split('.')[1];
payload = payload.Replace('-', '+').Replace('_', '/');
var base64 = payload.PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');
var token = Convert.FromBase64String(base64);