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

Posted

技术标签:

【中文标题】UseJwtBearerAuthentication 失败并显示 IDX10504:无法验证签名,令牌没有签名【英文标题】:UseJwtBearerAuthentication fails with IDX10504: Unable to validate signature, token does not have a signature 【发布时间】:2016-11-25 03:46:24 【问题描述】:

使用 ASP.NET Core 1.0 (rtm) 和我制作的 minimal verifiable sample,我看到我制作的 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 方法配置有:

        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;
        

这个问题其实归结为:

    在 Asp.net core 1.0 rtm 中,创建将通过中间件质询的令牌的最少步骤是什么?

    我是否只是遗漏了一些简单的步骤(可能只有一行代码)才能使这个演示工作,包括“签名”工作?

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

【问题讨论】:

有用信息:stormpath.com/blog/token-authentication-asp-net-core 【参考方案1】:

在 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 不记名中间件,而在于你如何生成自己的令牌。实现自己的令牌发行者酱很好,但使用像 OAuth2 或 OpenID Connect 这样的标准通常更好且更易于使用(例如,当拥有 OIDC 服务器时,您不必配置 JWT 承载中间件,因为它会直接下载使用OIDC discovery签名密钥)。

请随时阅读其他SO answer 了解更多信息。

【讨论】:

我想我已经有一个 SigningCredentials 对象。所以也许我很接近了。 你已经注入SigningCredentials作为构造函数参数,为什么不简单地流动呢? 你摇滚先生。请接受我卑微的赞美和崇拜。 实际换一班:github.com/wpostma/JsonWebTokenSample/commit/…

以上是关于UseJwtBearerAuthentication 失败并显示 IDX10504:无法验证签名,令牌没有签名的主要内容,如果未能解决你的问题,请参考以下文章