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

UseJwtBearerAuthentication fails with IDX10504: Unable to validate signature, token does not have a signature

使用 ASP.NET Core 1.0 (rtm),以及我生成的 minimal verifiable sample,我发现我生成的 JSON Web 令牌没有通过 .net核心 json 网络令牌中间件要求挑战,并因以下错误而失败:

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 方法配置有:

        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 核心 1.0 rtm 中,创建将通过中间件挑战的令牌的最少步骤是什么?

  2. 我是否只是遗漏了一些简单的步骤(也许只有一行代码)可以使这个演示正常工作,包括让 "signing" 正常工作?

  3. 考虑到 demo 仍然是一段可怕的代码,没有人应该在生产中使用它(因为我已经为此感到羞耻),我希望这个问题仍然可以阐明如何使 UseJwtBearerAuthentication 系统实际工作,至少在演示规模上如此。

In Asp.net core 1.0 rtm, what are the minimal steps to create a token that will pass the middleware challenge? Am I simply missing some simple step (as little as one line of code perhaps) that would make this demo work, including having "signing" work?

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
    );

解决这个问题,它应该可以工作。

Given that the demo is still a horrible piece of code, and nobody should ever use it in production (because I'm already ashamed of it), my hope is this question can still be illuminating as to how to make the UseJwtBearerAuthentication system actually work, at least at a demo scale.

其实问题不在于你如何使用JWT承载中间件,而在于你如何生成你自己的token。实现你自己的令牌发行者酱汁很好,但使用像 OAuth 2.0 或 OpenID Connect 这样的标准通常更好,更容易使用(例如,当有 OIDC 服务器时,你不必配置 JWT 承载中间件,因为它会直接下载使用 OIDC discovery).

的签名密钥

欢迎阅读其他 了解更多信息。