首页 > 解决方案 > 统一解码 JWT

问题描述

我有一个问题,我现在完全不知所措。我有一个身份验证服务器,可以创建 JWT 并将其发送到统一应用程序(android/VR)。

身份验证服务器这样创建令牌

        private string GenerateJwtToken(User user)
        {
            var symmetricKey = Convert.FromBase64String(_tokenSettings.Secret);

            var expires = DateTime.Now.AddMinutes(Convert.ToInt32(15));

            var tokenHandler = new JwtSecurityTokenHandler();

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.PrimarySid, user.Id.ToString()),
                    new Claim(ClaimTypes.Name, user.Username),
                    new Claim(ClaimTypes.GivenName, user.FirstName),
                    new Claim(ClaimTypes.Surname, user.LastName),
                    new Claim("company", user.Company),
                    new Claim(ClaimTypes.Role, "api_user"),
                    new Claim(ClaimTypes.Expiration, $"{expires.ToShortDateString() + " " + expires.ToShortTimeString()}"),
                }),

                Expires = expires,

                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(symmetricKey),
                    SecurityAlgorithms.HmacSha256Signature)
            };

            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(securityToken);

            return token;
        }

我对此进行解码并在控制台应用程序中提出声明没有任何问题。这就是混乱的来源。当我尝试在 Unity 中执行相同的任务并将应用程序构建到 VR 耳机时,我遇到了问题,即

"IDX10729: Unable to decode the header 'header' as Base64Url encoded string. jwtEncodedString: 'Token here'."

unity auth 服务看起来像这样

        public async Task<string> GetAccessToken(string username, string password)
        {
            using (var client = new HttpClient())
            {
                using (var request = new HttpRequestMessage())
                {
                    //TODO: Replace this hardcoded URL value here.
                    request.RequestUri = new Uri("{{URL Emmited}}");
                    request.Method = HttpMethod.Post;

                    var body = new AuthRequest()
                    {
                        Username = username,
                        Password = password
                    };

                    var content = new StringContent(JsonConvert.SerializeObject(body), encoding: Encoding.UTF8, "application/json");

                    request.Content = content;

                    var response = await client.SendAsync(request);

                    var responseContent = await response.Content.ReadAsStringAsync();

                    var tokenContent = JsonConvert.DeserializeObject<Response>(responseContent);

                    var token = tokenContent.Token;

                    return token;
                }
            }
        }

并检索索赔,我尝试了两种不同的方法

        public string GetUserName(string token)
        {
            try
            {
                var securityToken = new JwtSecurityToken(token);
                return securityToken?.Claims.First(claim => claim.Type == "given_name").Value;
            }
            catch (Exception exception)
            {
                //log exception here
                return string.Empty;
            }
        }

        public string GetUserName(string token)
        {
            try
            {
                var handler = new JwtSecurityTokenHandler();
                var securityToken = handler.ReadJwtToken(token);

                return securityToken?.Claims.First(claim => claim.Type == "given_name").Value;
            }
            catch (Exception exception)
            {
                //log exception here
                return string.Empty;
            }
        }

ReadJwtToken 在内部只是创建了一个新的 JwtSecurityToken 对象,所以我认为我缺少一些东西。

这两个都抛出相同的“无法将标头'header'解码为Base64Url编码字符串”错误,但是,如果我这样做handler.CanReadToken(token);返回true,这让我更加困惑。

任何人都知道为什么会发生这种情况以及如何解决它的任何线索。

一些进一步的信息;我检索到的令牌可以在 JWT.io 和控制台应用程序中解码,我使用 System.IdentityModel、System.IdentityModel.Tokens.JWT、System.IdentityModel.Tokens、System.IdentityModel.Logging 的 dotnet 标准 2.0 程序集和 Newtonsoft.Json

标签: c#unity3djwt

解决方案


推荐阅读