Google OpenIDConnect returns Base64 token that cannot be parsed
As an exercise to understand OpenIDConnect, I am trying to authenticate to my web app with Google according to this tutorial .
The problem is that I cannot read the token that google is sending to my app>
var bytes = Convert.FromBase64String(codeEx.Id_token);
var token = Encoding.ASCII.GetString(bytes);
The first line fails: "The input is not a valid Base-64 string because it contains a non-base 64 character, more than two indents, or an invalid character among the padding characters."
The document states: "The ID token is a cryptographically signed JSON object encoded in base 64".
For obvious reasons, I cannot put the token here. I tried:
- Input is not a valid Base-64 string because it contains a non-base 64 character
- Add '=' until the length is a multiple of 4.
- Together.
I get a code swap response and deserialize it using the NewtonSoft.Json library:
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>();
I don't know if there are any potential encoding issues. I see several "-'s" in the sign.
Any idea on how to read the token?
source to share
Use decoding base64url
(instead of normal base64
) after deserializing the compact representation of the token, as in:
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);
source to share
From this post :
"id_token" is encoded in a format called JSON Web Token (JWT). JWT - concatenation of "title", "body", "signature" by periods (.).
So, you only need to split id_token
by .
and decode the second segment:
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]);
source to share