作为理解OpenIDConnect的练习,我正试图按照本指南在我的web应用程序中与谷歌进行身份验证。
问题是我无法读取谷歌发送到我的应用程序的令牌>
var bytes = Convert.FromBase64String(codeEx.Id_token);
var token = Encoding.ASCII.GetString(bytes);
它在第一行失败:"输入不是有效的Base-64字符串,因为它包含非Base-64字符、两个以上的填充字符或填充字符中的非法字符。"
该文档指出:"ID令牌是一个以64为基础编码的加密签名JSON对象。"
出于显而易见的原因,我不能把代币放在这里。我试过:
- 输入不是有效的Base-64字符串,因为它包含非Base-64字符
- 添加"=",直到长度为4的倍数
- 所有这些
我得到代码交换响应,并使用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>();
我不知道编码是否有任何潜在的问题。我可以在代币中看到几个"-"one_answers"_"。
知道如何阅读代币吗?
在对令牌的紧凑表示进行反序列化后使用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);
来自这篇文章:
"id_token"以一种称为JSON Web令牌(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]);