JWT Token身份验证,过期令牌仍在工作,.net核心Web Api

时间:2017-03-27 11:22:17

标签: authentication token jwt .net-core

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

前言 - 我已根据https://stormpath.com/blog/token-authentication-asp-net-corehttps://dev.to/samueleresca/developing-token-authentication-using-aspnet-core实施了令牌身份验证。我还在github上阅读了一些问题,并在此处阅读。

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

在实施之后,我感觉我错过了什么。

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

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

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

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

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

此外 - 如果这是一个永久刷新的令牌,如果令牌遭到入侵,我是否应该关注安全性?

感谢您的帮助

4 个答案:

答案 0 :(得分:17)

我认为这与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
            }
        });

答案 1 :(得分:0)

如果您的到期时间远远超过默认时间(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"]))
        };
    });

答案 2 :(得分:0)

库本身会额外延迟5分钟。

如果按照指示的有效时间设置1分钟,则总计为6分钟。如果设置为1小时,则总计为1小时5分钟。

答案 3 :(得分:0)

就我而言,我添加了一个新的 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 分钟后过期。