我正在构建一个 .net core Web api。
前言 - 我已经按照https://stormpath.com/blog/token-authentication-asp-net-core和https://dev.to/samueleresca/developing-token-authentication-实现了令牌身份验证使用-aspnet-core。我还在 github 和 SO 上阅读了一些问题。
这也派上了用场https://goblincoding.com/2016/07/24/asp-net-core-policy-based-authorization-using-json-web-tokens/。
实施完这一切后,我感觉自己错过了一些东西。
我创建了一个位于 Web 客户端中的简单 Angular 应用程序。当我进行身份验证时,客户端会收到一个令牌。我现在将其存储在会话中(仍在开发中,因此稍后将解决存储位置的安全问题)。
不太确定这个(JWT(JSON Web令牌)自动延长过期时间)是否有用,因为据我所知,我还没有实现刷新令牌。
我注意到,当我调用注销,然后再次登录时,客户端会按照预期发送一个新令牌。但是,如果令牌过期时间已过(我将其设置为 1 分钟进行测试),然后刷新页面,则令牌在我的应用程序中似乎保持不变。 即好像令牌永远不会过期?!
我希望客户端返回 401 未经授权的错误,然后我可以强制用户重新进行身份验证。
这不是应该如何工作吗?默认情况下后台是否有一些自动刷新令牌魔法(我没有在教程中明确设置任何刷新令牌的概念)?或者我是否遗漏了令牌身份验证概念的某些内容?
另外 - 如果这是一个永久刷新的令牌,如果该令牌曾经被泄露,我是否应该担心安全性?
感谢您的帮助
我相信这与 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
}
});
如果您的过期时间远超过默认值(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"]))
};
});
图书馆本身会额外延迟5分钟。
如果您将到期时间设置为 1 分钟,则总计将为 6 分钟。如果您设置 1 小时,则总共将是 1 小时 5 分钟。
就我而言,我添加了一个新的 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;
}
这里的token将在10分钟后过期。
JWT 通常会额外增加 5 分钟到期时间, 如果您生成的令牌的有效期为 5 分钟,则会额外增加 5 分钟。 经验:5+5 = 10 经验:60+5 = 65
希望对你有帮助