【问题标题】:.NetCore JwtBearerAuthentication not rejecting expired tokens.Net Core JwtBearer 身份验证不拒绝过期令牌
【发布时间】:2017-10-30 07:50:27
【问题描述】:

我正在生成用于我的 WebApi 项目的 JWT。我将令牌设置为在一分钟内过期,以便我可以测试它是否在过期日期之后提交时拒绝令牌。

创建令牌控制器

public async Task<IActionResult> CreateToken([FromBody] CredentialModel model)
{
    var user = await _unitOfWork.UserManager.FindByNameAsync(model.UserName);

    if (user == null) return BadRequest();
    if (Hasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) !=
        PasswordVerificationResult.Success) return BadRequest();

    var userClaims = await UserManager.GetClaimsAsync(user);

    var claims = new[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
        new Claim(JwtRegisteredClaimNames.GivenName, user.FirstName), 
        new Claim(JwtRegisteredClaimNames.FamilyName, user.LastName),
        new Claim(JwtRegisteredClaimNames.Email, user.Email)
    }
    .Union(userClaims);

    var cert = new Certificate(Configuration["Tokens:Certificate"]);
    var token = new JwtSecurityToken(
        issuer: Configuration["Tokens:Issuer"],
        audience: Configuration["Tokens:Audience"],
        claims: claims,
        expires: DateTime.UtcNow.AddMinutes(1),
        signingCredentials: cert.Signature
    );

    return Ok(new
    {
        token = new JwtSecurityTokenHandler().WriteToken(token),
        expiration = token.ValidTo
    });
}

令牌认证 - 启动类

app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = new TokenValidationParameters()
    {
        ValidIssuer = Configuration["Tokens:Issuer"],
        ValidAudience = Configuration["Tokens:Audience"],
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new Certificate(Configuration["Tokens:Certificate"]).SecurityKey,
        ValidateLifetime = true
    },
});

虽然我设置了 validateLifetime = true,但两分钟后令牌不会被拒绝。它将继续接受令牌。是否有我不知道的最短到期时间或我的设置有误?

【问题讨论】:

  • 我不认为您有此代码的可运行版本,是吗?无论如何,我查找了 UseJwtBearerAuthentication 的文档,看起来它已被弃用:/ github.com/aspnet/Security/blob/…
  • @MariaInesParnisari 是的,我的代码正在运行,并且令牌的发行和验证工作。除了我编写的用于导入非对称 X509Certificate2 的小型证书类之外,它几乎都在那里。它似乎并不总是验证到期。我查看了您的链接,它似乎已被弃用。但我看不出是什么取代了它。
  • 我的意思是如果这段代码托管在 GitHub 中,我可以下载并自己尝试。当您说验证有效时,您是否尝试过手动更改令牌的任何其他属性(例如观众)以查看它是否失败?
  • 在客户的私人仓库中没有。我实际上只是偶然发现了这里的解决方案。 stormpath.com/blog/token-authentication-asp-net-core。这是一个时间 Clockskew 属性,允许一定量的时钟漂移。我假设有一个默认的漂移值。如果我将它设置为 TimeSpan.Zero,它会完美运行。我仍然担心弃用。我想我将不得不寻找它的替代品。

标签: c# asp.net-core jwt asp.net-core-identity


【解决方案1】:

如果有人感兴趣,我偶然发现了here 的答案。 ClockSkew 的默认值为 5 分钟。

app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    TokenValidationParameters = new TokenValidationParameters()
    {
        ValidIssuer = Configuration["Tokens:Issuer"],
        ValidAudience = Configuration["Tokens:Audience"],
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new Certificate(certPath: Configuration["Tokens:Certificate"], isValid: false).SecurityKey,
        ValidateLifetime = true,
        ValidateIssuer = true,
        ValidateAudience = true,
        ClockSkew = TimeSpan.Zero
    },
});

【讨论】:

  • 小心时钟偏差设置为零。您可能会遇到一些客户的问题。
  • @CyprienAutexier 虽然这是真的,但大的过期窗口可能不会有问题。对于相反的情况:到期窗口较小,如果您对令牌的到期速度有严格要求,您可能确实想要限制时钟偏差
  • @CyprienAutexier 1 分钟到期仅用于测试。我会增加产量。 Clockskew 和过期长度的任何推荐值。
  • @Dblock247 我从来没有对默认值有任何问题,我认为是 5 分钟。但我不会假装自己是安全专家。
  • 您可以随时使用ClockSkew = Debugger.IsAttached ? TimeSpan.Zero : TimeSpan.FromMinutes(10),因此在调试期间您无需处理它——假设您使用的是自己的机器或您知道时间正确的机器。但是,如果您忘记将其更改回来,您以后不会遇到麻烦。
猜你喜欢
  • 2019-02-22
  • 2020-02-05
  • 2020-09-21
  • 2017-12-15
  • 2018-08-03
  • 2021-01-10
  • 2015-11-12
  • 1970-01-01
相关资源
最近更新 更多