c# - .net core 解码的 JWT 声明类型与生成时使用的类型不匹配

标签 c# .net .net-core

我正在 .net core 3.1 中生成 JWT token ,如下所示

    private string GenerateJwtToken(User user)
    {
        var tokenHandler = new JwtSecurityTokenHandler();

        var key = Encoding.ASCII.GetBytes(_authenticationSettings.Secret);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.Username),
                new Claim(ClaimTypes.Email, user.Email),
                new Claim(ClaimTypes.GivenName, user.FirstName)
            }),
            Expires = DateTime.UtcNow.AddDays(_authenticationSettings.AuthTokenValidityInDays),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

        var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);

        return tokenHandler.WriteToken(token);
    }

在我的单元测试中,我尝试像这样测试它

    [Fact]
    public async Task Should_Authenticate_With_Valid_CredentialsAsync()
    {
        var tokenString = await _sut.Authenticate(new User 
        { 
            Username = "test",
            Email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3d49584e497d5b5c5658505c5451135e5250" rel="noreferrer noopener nofollow">[email protected]</a>",
            FirstName = "Someone"
        });
        var jwtHandler = new JwtSecurityTokenHandler();
        Assert.True(jwtHandler.CanReadToken(tokenString));

        var token = new JwtSecurityToken(tokenString);
        Assert.Equal("test", token.Claims.First(claim => claim.Type == ClaimTypes.NameIdentifier).Value);
    }

第一个 Assert 通过,但第二个由于空引用异常而失败。我检查了代码并查看了 nameid 类型的用户名声明。测试期间,键 ClaimTypes.NameIdentifier 的值似乎是 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier而不是 nameid

有人可以帮助解释发生了什么以及如何解决它吗?

最佳答案

好吧,经过一番深入研究,我终于找到了答案。所以我需要做的是这样的事情(它获取一个可以使用静态类型查询的 ClaimsPrincipal )

        var validationParameters = new TokenValidationParameters
        {
            IssuerSigningKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes("my-super-secret-test-key")), SecurityAlgorithms.HmacSha256Signature).Key,
            ValidateAudience = false,
            ValidateIssuer = false,
        };

        SecurityToken validatedToken;
        JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
        var user = handler.ValidateToken(tokenString, validationParameters, out validatedToken);

        Assert.Equal("test", user.FindFirst(ClaimTypes.NameIdentifier).Value);

关于c# - .net core 解码的 JWT 声明类型与生成时使用的类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62548869/

相关文章:

c# - CSV实际上是....分号分隔值...(AZERTY上的Excel导出)

c# - 如何使用 C# 以编程方式复制 MS SQL 2000 数据库?

c# - .net 核心 IActionResult 返回 OK()

c# - 如何将 MySQL 与 .NET Core 3 和 Entity Framework 6 集成

c# - Emgu OpenCV .Net 包装器中的 TColor 在哪里定义?

c# - 是否有任何可能的方法来连接来自使用 2 个不同 DbContexts 的 2 个不同数据库的 2 个表?

java - C# 实现 - "Print all combinations of balanced parentheses"

c# - 从 C# 运行时 SQL 查询超时,在 SQL Server Management Studio 中运行速度很快

c# - ReactiveUI 的 BindTo 和 ToProperty 方法有什么区别?

c# - LINQ InvalidCastException 错误