【问题标题】:Unable to read JWT token generated using System.IdentityModel.Tokens.Jwt无法读取使用 System.IdentityModel.Tokens.Jwt 生成的 JWT 令牌
【发布时间】:2019-10-08 10:40:43
【问题描述】:

我们已经开始开发一个新项目,并正在考虑使用 Identity Server/OpenId 来满足授权和身份验证需求。由于在阅读 Microsoft 的 Jwt 类和支持并尝试一些示例代码之前,我没有使用过 Jwt 令牌。我从 Nuget 安装了 System.Identitymodel.Tokend.Jwt 5.4 版并使用下面的示例代码(我在堆栈溢出中找到)生成了令牌

        string strToken = string.Empty;

        string strKey = "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1";
        var vSymmetricSecurityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(strKey));
        var vSigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(vSymmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
        var header = new JwtHeader(vSigningCredentials);
        var payload = new JwtPayload
        {
            { "Id", "userId" },
            { "Role", "userrole" },
            { "FirstName", "first_name" },
            { "LastName", "last_name" },
            { "EmailAddress", "email_address" },
            { "TenantId", "tenant_id" },
        };
        var secToken = new JwtSecurityToken(header, payload);
        var handler = new JwtSecurityTokenHandler();
        strToken = handler.WriteToken(secToken);

令牌已成功生成。但是当我去阅读令牌时,我收到以下错误

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

如果我将令牌粘贴到 JWT - 它告诉我签名无效。有什么不正确的地方?

生成的令牌是 eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6InVzZXJJZCIsIlJvbGUiOiJ1c2Vycm9sZSIsIkZpcnN0TmFtZSI6ImZpcnN0X25hbWUiLCJMYXN0TmFtZSI6Imxhc3RfbmFtZSIsIkVtYWlsQWRkcmVzcyI6ImVtYWlsX2FkZHJlc3MiLCJUZW5hbnRJZCI6InRlbmFudF9pZCJ9.BXUFKLcVmnGxRG5yGRNYVLTU2gT_F_AmBGev6sWhQd0 P>

【问题讨论】:

  • 请将导致错误的令牌添加到您的问题中。
  • 在问题中附加了令牌谢谢@jps

标签: c# authentication oauth jwt


【解决方案1】:

就我而言,这是错误的 OAuth Bearer Token。仔细检查它,例如它可以在字符串的开头有两次“Bearer”

【讨论】:

    【解决方案2】:

    您使用了错误的密钥类型和算法。 JWT 使用公钥/私钥而不是对称密钥。

    此外,JWT 声明(有效负载)的内容也有一个标准。您缺少诸如已签发、到期时间等字段的项目。解决签名问题后,如果您需要有关 JWT 声明的帮助,请创建一个新问题,因为这是一个非常不同的主题。

    注意:strKey 应该是密钥对的私钥。公钥用于验证 JWT(称为 JWS)的签名。

    更改这些行:

    var vSymmetricSecurityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(strKey));
    var vSigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(vSymmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
    

    到:

    var vRsaSecurityKey = new Microsoft.IdentityModel.Tokens.RsaSecurityKey(privateKey);
    var vSigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(vSymmetricSecurityKey, SecurityAlgorithms.RsaSha256Signature);
    

    【讨论】:

    • “JWT 使用公钥/私钥而不是对称密钥”——你不能只是这么说!使用 JWT 的特定服务可能仅支持具有公钥/私钥的某些算法,但 JWT 通常可以与广泛的算法一起使用,包括例如具有对称密钥的 HS256。
    • @jps - 你是对的。我将更改措辞以针对此问题。
    猜你喜欢
    • 2022-01-14
    • 2013-09-11
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 2020-06-23
    • 2021-05-31
    相关资源
    最近更新 更多