【问题标题】:JWT Token authentication, expired tokens still working, .net core Web ApiJWT 令牌认证,过期令牌仍然有效,.net core Web Api
【发布时间】:2017-08-20 01:54:46
【问题描述】:

我正在构建一个 .net core web api。

前言 - 我已经按照 https://stormpath.com/blog/token-authentication-asp-net-corehttps://dev.to/samueleresca/developing-token-authentication-using-aspnet-core 实现了令牌身份验证。我还在 github 和 SO 上阅读了一些问题。

这也派上了用场https://goblincoding.com/2016/07/24/asp-net-core-policy-based-authorisation-using-json-web-tokens/

在实施完这一切之后,我觉得我错过了一些东西。

我创建了一个简单的 Angular 应用程序,它位于 Web 客户端中。当我进行身份验证时,客户端会收到一个令牌。我现在将其存储在会话中(仍在开发中,因此将解决有关稍后存储位置的安全问题)。

我不确定这 (JWT (JSON Web Token) automatic prolongation of expiration) 是否有用,因为据我所知,我还没有实现刷新令牌。

我注意到,当我调用注销,然后再次登录时,客户端会收到一个新令牌 - 正如预期的那样。但是,如果令牌过期时间已过(我将其设置为 1 分钟以进行测试)然后刷新页面,则令牌在我的应用程序中似乎保持不变。 即好像令牌永不过期?!

我本来希望客户端返回 401 Unauthorized 错误,然后我可以强制用户重新进行身份验证。

这不是应该如何工作的吗? 在后台是否有一些默认的自动刷新令牌魔术(我没有在教程中明确设置任何刷新令牌的概念)?还是我错过了令牌身份验证的概念?

另外 - 如果这是一个永久刷新的令牌,如果令牌被泄露,我是否应该担心安全性?

感谢您的帮助

【问题讨论】:

    标签: authentication token jwt .net-core


    【解决方案1】:

    我认为这与 JwtBearerOptions 中的 ClockSkew 有关。

    更改为 TimeSpan.Zero,因为我相信默认设置为 5 分钟(虽然不是 100% 确定)。

    我在下面发布了一些示例代码,这些示例代码将放置在 Startup.cs => 配置中。

            app.UseJwtBearerAuthentication(new JwtBearerOptions()
            {
                AuthenticationScheme = "Jwt",
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidAudience = Configuration["Tokens:Audience"],
                    ValidIssuer = Configuration["Tokens:Issuer"],
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                }
            });
    

    【讨论】:

    【解决方案2】:

    如果您的过期时间远超过默认值(5 分钟)或超过我设置的时间,并且它仍然认为过期令牌有效,并且将 ClockSkew 设置为 TimeSpan.Zero 无效,请确保你有财产

    ValidateLifetime 
    

    设置为 true,因为我将我的设置为 false 导致问题,这完全有道理,但很容易疏忽。

    services.AddAuthentication(option =>
        {
            option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["JwtToken:Issuer"],
                ValidAudience = Configuration["JwtToken:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(
                   Encoding.UTF8.GetBytes(Configuration["JwtToken:SecretKey"]))
            };
        });
    

    【讨论】:

    【解决方案3】:

    图书馆本身还有 5 分钟的额外延迟。

    如果您将到期时间设置为 1 分钟,则总计为 6 分钟。如果设置为 1 小时,则总时间为 1 小时 5 分钟。

    【讨论】:

    • 图书馆本身额外延迟 5 分钟是什么意思?你的意思是除了已经提到的ClockSkew吗?
    • 他的意思是已经提到的ClockSkew我会说。
    • 也许吧,但是关于 ClockSkew 已经有了一个很好且明确的答案,那么为什么我们需要一个额外的、非常不清楚的答案呢?
    • 是的,我说的是 ClockSkew,这是我发现的一种例证方式。
    【解决方案4】:

    在我的例子中,我添加了一个新的 SecurityTokenDescriptor,其中包含根据我们的要求采用当前日期和时间并过期的属性。 下面是一个带有 post 请求的示例登录控制器,该控制器又返回带有令牌的用户详细信息。

            public async Task<ActionResult<UserWithToken>> Login([FromBody] User user)
            {
                 user = await _context.Users
                                        .Include(u => u.Reservations)
                                    .Where(u => u.Email == user.Email
                                       && u.Password == user.Password)
                                    .FirstOrDefaultAsync();
    
                if (user == null)
                {
                    return NotFound();
                }
    
                UserWithToken userWithToken = new UserWithToken(user);
    
                if (userWithToken == null)
                {
                    return NotFound();
                }
    
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(_jwtsettings.SecretKey);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim(ClaimTypes.Name, user.Email)
                    }),
                    Expires = DateTime.UtcNow.AddMinutes(10),
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
                    SecurityAlgorithms.HmacSha256Signature)
                };
                var token = tokenHandler.CreateToken(tokenDescriptor);
                userWithToken.Token = tokenHandler.WriteToken(token);
    
                return userWithToken;
            }
    

    这里的令牌将在 10 分钟后过期。

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 2021-06-27
      • 1970-01-01
      • 2020-01-09
      • 2018-10-07
      • 2018-07-18
      • 2019-02-22
      • 2019-01-21
      • 1970-01-01
      相关资源
      最近更新 更多