UseJwtBearerAuthentication失败,IDX10504:无法验证签名,令牌没有签名

本文关键字:令牌 验证 失败 IDX10504 UseJwtBearerAuthentication | 更新日期: 2023-09-27 17:58:07

使用ASP.NET Core 1.0(rtm),使用我制作的可验证样本,我发现我制作的JSON Web令牌没有通过.NET Core JSON Web令牌中间件声明挑战,并失败,出现以下错误:

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: 
IDX10504: Unable to validate signature, token does not have a signature: 
'... ... token value here...'

我制作了一个最小的示例,它在ASP.NET Core RC1中运行良好,但在RTM中不起作用。我没有移植到RC2进行测试,但我认为这样的测试毫无意义。您可以使用提供的测试脚本进行演示:

 python tests'testloginapi.py
  GET OK: 200 http://localhost:54993/authorize/login?username=TEST&pas...
  POST OK: 200 http://localhost:54993/authorize/login?username=TEST&pas...
  authorization token received... eyJhbGciOi...
  expected status 200 but got 401 for GET http://localhost:54993/authorizetest/test

我的最小示例的突出点是:

Startup.cs方法Configure有:

        app.UseJwtBearerAuthentication(_keyArtifacts.getJwtBearerOptions());

承载选项如下:

  public static JwtBearerOptions CreateJwtBearerOption(RsaSecurityKey key, string tokenIssuer, string tokenAudience)
        {
            var jwtBearerOptions = new JwtBearerOptions();

            jwtBearerOptions.AutomaticAuthenticate = true;
            jwtBearerOptions.AutomaticChallenge = true;
            jwtBearerOptions.TokenValidationParameters.ValidateIssuerSigningKey = true;
            jwtBearerOptions.TokenValidationParameters.IssuerSigningKey = key;
            jwtBearerOptions.TokenValidationParameters.ValidIssuer = tokenIssuer;
            jwtBearerOptions.TokenValidationParameters.ValidateIssuer = true;
            jwtBearerOptions.TokenValidationParameters.ValidateLifetime = true;
            jwtBearerOptions.TokenValidationParameters.ClockSkew = TimeSpan.Zero;

            jwtBearerOptions.TokenValidationParameters.ValidAudience = tokenAudience;
            return jwtBearerOptions;
        }

这个问题实际上可以归结为:

  1. 在Asp.net core 1.0 rtm中,创建一个能够通过中间件挑战的令牌的最低步骤是什么?

  2. 我是不是只是错过了一些简单的步骤(可能只有一行代码),这些步骤可以让这个演示发挥作用,包括"签名"工作?

  3. 考虑到演示仍然是一段可怕的代码,任何人都不应该在生产中使用它(因为我已经为此感到羞愧),我希望这个问题仍然可以启发我们如何使UseJwtBearerAuthentication系统真正工作,至少在演示规模上是这样。

UseJwtBearerAuthentication失败,IDX10504:无法验证签名,令牌没有签名

在Asp.net core 1.0 rtm中,创建一个能够通过中间件挑战的令牌的最低步骤是什么?我只是错过了一些简单的步骤(可能只有一行代码),这将使这个演示工作,包括";签署";工作

IdentityModel(负责验证JWT承载中间件接收到的令牌的库)无法验证JWT令牌,因为它们实际上没有任何签名,正如您看到的错误中所解释的那样。

缺少签名可能是因为您在创建自己的令牌时没有分配SecurityTokenDescriptor.SigningCredentials

JwtSecurityTokenHandler handler = BearerOptions
    .SecurityTokenValidators
    .OfType<JwtSecurityTokenHandler>()
    .First();
var tokenData = new SecurityTokenDescriptor
{
    
    Issuer = BearerOptions.TokenValidationParameters.ValidIssuer,
    Audience = BearerOptions.TokenValidationParameters.ValidAudience,
    Subject = new ClaimsIdentity(claims),
    Expires = DateTime.Now.AddDays(1),
    NotBefore = DateTime.Now
};
/*JwtSecurityToken*/
var securityToken =
    handler.CreateToken
    (
        tokenData
    );

修复它,它应该会起作用。

考虑到演示仍然是一段可怕的代码,任何人都不应该在生产中使用它(因为我已经为此感到羞愧),我希望这个问题仍然可以启发我们如何使UseJwtBearerAuthentication系统真正工作,至少在演示规模上是这样。

实际上,问题不在于如何使用JWT承载中间件,而在于如何生成自己的令牌。实现您自己的令牌颁发者酱是可以的,但使用OAuth 2.0或OpenID Connect等标准通常更好、更容易使用(例如,当拥有OIDC服务器时,您不必配置JWT承载中间件,因为它将使用OIDC发现直接下载签名密钥)。

请随意阅读其他SO答案以获取更多信息。