我正在构建一个.net核心web api。
前言 - 我已根据https://stormpath.com/blog/token-authentication-asp-net-core和https://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错误,然后我可以强制用户重新进行身份验证。
这不是这个应该如何工作吗?在后台是否有一些默认的自动刷新令牌魔法(我没有明确地在教程中设置任何刷新令牌的概念) )?或者我错过了一些关于令牌身份验证的概念?
此外 - 如果这是一个永久刷新的令牌,如果令牌遭到入侵,我是否应该关注安全性?
感谢您的帮助
答案 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 分钟后过期。