【问题标题】:Token handler unable to convert the token to jwt token令牌处理程序无法将令牌转换为 jwt 令牌
【发布时间】:2019-07-13 16:38:20
【问题描述】:

我正在尝试使用 JwtSecurityTokenHandler 将我的令牌字符串转换为 jwt 令牌。但是这样说会出错

IDX12709:CanReadToken() 返回错误。 JWT 格式不正确:“[PII is hidden]”。\n令牌需要采用 JWS 或 JWE 紧凑序列化格式。 (JWS):'EncodedHeader.EndcodedPayload.EncodedSignature'。 (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'。

我该如何解决这个问题?

这是我的令牌

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluIiwibmJmIjoxNTUwNjM3NzcxLCJleHAiOjE1NTA2Mzg5NzEsImlhdCI6MTU1MDYzNzc3MX0.tUcoyoHgkrX3rDKl0cRLd9FwLtRprQpgYepMoiekixY P>

var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

调用 web api

using (HttpClient client = new HttpClient())
            {
                string path = "UserMaintenance/ValidateUserId?userid=" + txtUsername.Text.Trim().ToString();
                client.BaseAddress = new Uri(GlobalData.BaseUri);
                client.DefaultRequestHeaders.Add("Authorization", "Bearer" + GlobalData.Token);
                HttpResponseMessage response = client.GetAsync(path).Result;
                if (response.IsSuccessStatusCode)
                {
                    var value = response.Content.ReadAsStringAsync().Result;
                    isValid = JsonConvert.DeserializeObject<bool>(value);
                }
            }

这是我的 GetPrincipal 方法

public static ClaimsPrincipal GetPrincipal(string token)
    {
        try
        {
            var symmetricKey = Convert.FromBase64String(Secret);
            var validationParameters = new TokenValidationParameters()
            {
                RequireExpirationTime = true,
                ValidateIssuer = false,
                ValidateAudience = false,
                IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
            };

            var handler = new JwtSecurityTokenHandler();
            handler.InboundClaimTypeMap.Clear();

            SecurityToken securityToken;
            var principal = handler.ValidateToken(token, validationParameters, out securityToken);

            return principal;
        }

        catch (Exception ex)
        {
            return null;
        }
    }

【问题讨论】:

  • 能否将令牌添加到您的问题中?
  • 你的代码和我的代码都在使用这个令牌。异常到底是在哪一行抛出的?
  • 您是否跟踪了代码并检查了 jwt 是否在上述行中具有所需的值?并从令牌的开头删除了 “Bearer” 字样?
  • 我更新了我的答案。从标头中读取授权值后,您需要从字符串的开头删除承载,然后尝试将其解析为 jwt 令牌。
  • 初始化授权头时,缺少Bearer后面的空格。让我再澄清一点:想象一下 XXX 是你的代币。第一步,当你想调用一个api时,你需要在授权头中添加这个字符串:“Bearer XXX”。而在第二步中,当您要消费和解析令牌时,您需要从授权标头的开头删除 "Bearer" 并准确解析 XXX 的值,不带任何前缀。

标签: asp.net asp.net-web-api2 jwt


【解决方案1】:

对于 .net 框架 4.5.1,我在生成令牌时删除了我的自定义键,并在 JwtRegisteredClaimNames 的声明中使用默认值。

var claims = new[] 
{
     new Claim(JwtRegisteredClaimNames.GivenName, Data.UserName),
     new Claim(JwtRegisteredClaimNames.Prn,Data.Password),
     new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};

【讨论】:

    【解决方案2】:

    版本 5.6.0.0 - 当前是最新版本 可以使用与@thilim9 的问题中类似的代码。

    var tokenId = identity.Claims.SingleOrDefault(c => c.Type == "id_token")?.Value;
    var handler = new JwtSecurityTokenHandler();
    JwtSecurityToken token = handler.ReadJwtToken(tokenId);
    

    【讨论】:

      【解决方案3】:

      我就是这样做的,它对我有用:

      var token = new System.IdentityModel.Tokens.JwtSecurityToken(jwt);  
      

      以上行适用于System.IdentityModel.Tokens.Jwt 包版本4.0.0。 正如@Nick 评论的那样,在最新版本的包中,JwtSecurityToken 不再存在于以前的命名空间中,而是存在于System.IdentityModel.Tokens.Jwt 中,因此您需要编写: var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(jwt);

      除非您的令牌格式不正确。如果你也共享令牌会更好。

      更新:

      您还需要从令牌的开头删除单词“Bearer”(如果没有):

       var jwt = context.Request.Headers["Authorization"].Replace("Bearer ", string.Empty);
      

      【讨论】:

      • 命名空间“System.IdentityModel.Tokens”中不存在类型或命名空间名称“JwtSecurityToken”
      • @Nick 我仔细检查过,是的,它与版本有关。在System.IdentityModel.Tokens.Jwtversion=4.0.0 中,JwtSecurityToken 类在System.IdentityModel.Tokens 中,但在最新版本中,它已从命名空间中删除并放在System.IdentityModel.Tokens.Jwt 中。微软文档薄弱。
      • 最新版本没有删除。我回顾了 10 个版本,所有版本到 2016 年,它仍然在 System.IdentityModel.Tokens.Jwt 中。为什么要根据 2014 年发布的软件包的随机版本来回答这个问题,而在发布答案时已经有 17 个新版本?
      • 感谢您删除“Bearer”部分的提示。不过,我必须添加一个 .ToString() 调用以使其对我有用: var jwt = _httpContextAccessor.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", string.Empty) ;
      猜你喜欢
      • 2013-06-28
      • 2012-11-20
      • 1970-01-01
      • 2017-05-09
      • 2014-10-12
      • 2019-06-03
      • 2017-06-10
      • 2019-03-19
      • 2016-02-17
      相关资源
      最近更新 更多