【问题标题】:.net mvc JWT token changes utf-8 chars.net mvc JWT 令牌更改 utf-8 字符
【发布时间】:2020-03-17 06:44:02
【问题描述】:

我有一个用于身份验证的 JWT 令牌。在我的数据库中,我有一个 customerUser,它包含一个 firstName: Tim 和一个 lastName: Børge,但是在我的代码从我的数据库中读取并创建一个 JWT 之后,令牌中的结构使得它

"firstName":"Tim"
"lastName":"Børge"

这就是我存储在本地存储中的内容。当我在网页上打印出用户名时,这是一个问题。我检查了我的源代码,这一切似乎都归结为这一行:

        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!");
        }

直到那时,我的数据都包含我的 UTF-8 字符。有什么想法吗?

编辑 智威汤逊:

eyJpc3MiOiJLb2xsZWN0by5pbyA0LjAiLCJpYXQiOjE1NzQzMzA3MTguMCwiZXhwIjoxNTc1NTQwMzE4LjAsInN1YmplY3QiOiJtYW5kQG5pcmFzLmRrIiwiYXVkIjoiS29sbGVjdG8uaW8gNC4wIiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJjdXN0b21lcl9pZCI6IjU5YTkyYWFmYWU3YTcxMWIzODkwMTc2MSIsImFwaV9rZXkiOiI1Y2M4MTE2MDdmYTlkNjg3ZDI2NTkyZmUiLCJjdXN0b21lclVzZXJfaWQiOiI1ZDljM2FmNGY3MThiNDRlOTBiYmJkMzMiLCJhY2NvdW50X2lkIjoxMDQ0LCJlbWFpbCI6Im1hbmRAbmlyYXMuZGsiLCJyb2xlcyI6WyJNb2JpbGVVc2VyIiwiTmlyYXNBZG1pbiIsIkFkbWluIl0sImdpdmVuX25hbWUiOiJNYWRzIiwiZmFtaWx5X25hbWUiOiJCw7h0a2VyIEFuZGVyc2VuIn0.OMx8VZesjvd92ZrfoSpAdICvl9bGP2UTQrFjYWDWpKY

我的功能:

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);
        }

【问题讨论】:

  • 好的,如果你去jwt.io你会看到字符以正确的形式显示,所以你的令牌是好的。
  • @Stefan - 是的,但jstoolset.com/jwt 产生不同的结果,我的网站也是如此。所以我的理论是 jwt.io 在客户端解码字符,我不想每次获得令牌时都在前端 js 中这样做

标签: c# asp.net base64 jwt


【解决方案1】:

token中的编码没有问题!

您的 JWT 编码方法以 base64url 编码正确编码您的 UTF-8 字符,jwt.io 正确显示解码后的 UTF-8 字符。

您的客户端和jstoolset.com/jwt 将解码的字符解释为 ISO-8859-1 或 Windows-1252 字符集。

很容易证明编码是正确的。

出于说明目的,我制作了一个更简单的令牌,其中包含丹麦 UTF-8 字符 ø 作为有效负载:

eyJhbGciOiJIUzI1NiJ9.eyLDuCI6IjEifQ.RR8UPmBsMqH-huDVtfRWK4FSrmBuNEDtoMPxE7hJWt8

有效载荷是:

{"ø":"1"}

如果您获取有效载荷eyLDuCI6IjEifQ,您首先必须将其转换回二进制文件。 base64字符e代表6位011110y代表110010等等(查看Wikipedia base64以获取完整的编码表)。现在我们必须将其转换回 8 位,因此取前 6 位加上下一个字符的前 2 位,这将给您01111011 或十六进制 7B{ 的 ASCII 值后跟 @ 987654335@(十六进制22,ASCII")等等。

第一个字符的完整转换产生以下十六进制代码:

7B 22 C3 B8 22

UTF-8 encoder/decoder 上,您可以看到ø 具有UTF-8 代码C3 B8,所有其他代码都可以在任何常见的ASCII 表中轻松找到:

{ " ø "

所以你看,令牌包含一个正确编码的 UTF-8 字符。由您的客户将结果解释为 UTF-8 而不是任何其他字符集。

【讨论】:

  • 太棒了——这让事情变得更清楚了。我将强制我的前端代码正确解释这一点:)
猜你喜欢
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2017-04-27
  • 2020-11-26
  • 2014-03-22
  • 1970-01-01
相关资源
最近更新 更多