Reputation: 752
I have a JWT token that I use for authentication. In my Database I have a customerUser that cointains a firstName: Tim
and a lastName: Børge
but after my code reads from my Database and creates a JWT the structure in the token makes it so that
"firstName":"Tim"
"lastName":"Børge"
And this is what I store in my localstorage. And that is a problem for when I print out the users name on my webpage. I have checked my source code and it all seems to boil down to this line:
try
{
var user = Membership.GetUser(username, true);
var jwt = GetJwtFromMembershipAccountId((int)(user?.ProviderUserKey??0));
return this.Request.CreateResponse(
HttpStatusCode.OK,
jwt,
new TextMediaTypeFormatter()
);
}
catch
{
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Error logging in!");
}
Up until that point my data contains my UTF-8 chars. Any ideas?
EDIT the JWT:
eyJpc3MiOiJLb2xsZWN0by5pbyA0LjAiLCJpYXQiOjE1NzQzMzA3MTguMCwiZXhwIjoxNTc1NTQwMzE4LjAsInN1YmplY3QiOiJtYW5kQG5pcmFzLmRrIiwiYXVkIjoiS29sbGVjdG8uaW8gNC4wIiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJjdXN0b21lcl9pZCI6IjU5YTkyYWFmYWU3YTcxMWIzODkwMTc2MSIsImFwaV9rZXkiOiI1Y2M4MTE2MDdmYTlkNjg3ZDI2NTkyZmUiLCJjdXN0b21lclVzZXJfaWQiOiI1ZDljM2FmNGY3MThiNDRlOTBiYmJkMzMiLCJhY2NvdW50X2lkIjoxMDQ0LCJlbWFpbCI6Im1hbmRAbmlyYXMuZGsiLCJyb2xlcyI6WyJNb2JpbGVVc2VyIiwiTmlyYXNBZG1pbiIsIkFkbWluIl0sImdpdmVuX25hbWUiOiJNYWRzIiwiZmFtaWx5X25hbWUiOiJCw7h0a2VyIEFuZGVyc2VuIn0.OMx8VZesjvd92ZrfoSpAdICvl9bGP2UTQrFjYWDWpKY
My function:
private string GetJwtFromMembershipAccountId(int accountId)
{
var account = DBHelper.membershipAccountCollection.FindOneById(accountId);
var customerUser = DBHelper.customerUserCollection.AsQueryable().FirstOrDefault(x => x.UserId == accountId);
var customer = DBHelper.customerCollection.AsQueryable().FirstOrDefault(x => x.CustomerId == customerUser.CustomerId);
var timeSinceEpoch = (DateTime.UtcNow - JwtValidator.UnixEpoch);
var expirationTime = timeSinceEpoch.Add(new TimeSpan(14, 0, 0, 0)); /* 14 days from now */
var kollectoAppHeader = WebConfigurationManager.AppSettings["App.Name"] + " " + WebConfigurationManager.AppSettings["App.Version"];
//var kollectoAppHeader = "SmartInspect";
var headers = new Dictionary<string, object>
{
{ "iss", kollectoAppHeader },
{ "iat", Math.Round(timeSinceEpoch.TotalSeconds) },
{ "exp", Math.Round(expirationTime.TotalSeconds) },
{ "subject", account.Username },
{ "aud", kollectoAppHeader }
};
var payload = new Dictionary<string, object>
{
{ "customer_id", customer.CustomerId.ToString() },
{ "api_key", customer.ApiKey.ToString() },
{ "customerUser_id", customerUser.CustomerUserId.ToString() },
{ "account_id", account.AccountId },
{ "email", customerUser.Email },
{ "roles", account.Roles },
{ "given_name", customerUser?.FirstName ?? string.Empty },
{ "family_name", customerUser?.LastName ?? string.Empty }
};
var algorithm = new HMACSHA256Algorithm();
var serializer = new JsonNetSerializer();
var urlEncoder = new JwtBase64UrlEncoder();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
return encoder.Encode(headers, payload, _ssoJwtPsk);
}
Upvotes: 3
Views: 2643
Reputation: 22505
There's nothing wrong with the encoding in the token!
Your JWT encode method correctly encodes your UTF-8 characters in base64url
encoding and jwt.io correctly displays the decoded UTF-8 characters.
Your client and jstoolset.com/jwt are interpreting the decoded characters as ISO-8859-1 or Windows-1252 charset.
It can easily be proved that the encoding is correct.
For illustration purposes, I made a simpler token which contains the danish UTF-8 character ø
as payload:
eyJhbGciOiJIUzI1NiJ9.eyLDuCI6IjEifQ.RR8UPmBsMqH-huDVtfRWK4FSrmBuNEDtoMPxE7hJWt8
the payload is:
{"ø":"1"}
If you take the payload eyLDuCI6IjEifQ
you first have to transform it back to binary. The base64 character e
stands for the 6 bits 011110
, y
for 110010
and so on (check Wikipedia base64 for the full encoding table). Now we have to transform it back to 8 bits, so take the first 6 bits plus the first 2 bits of the next character, that will give you 01111011
or hexadecimal 7B
, the ASCII value of {
followed by 00100010
(hex 22
, ASCII "
) and so on.
The full conversion of the first characters results in the following hex codes:
7B 22 C3 B8 22
On UTF-8 encoder/decoder you can see that ø
has the UTF-8 code C3 B8
, all others codes can easily be found on any common ASCII-table:
{ " ø "
So you see, the token contains a correctly encoded UTF-8 character. It's up to your client to interpret the result as UTF-8 and not any other character set.
Upvotes: 3