我目前正在系统中使用JwtSecurityToken类。标识模型。令牌命名空间。我使用以下内容创建令牌:
DateTime expires = DateTime.UtcNow.AddSeconds(10);
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var genericIdentity = new System.Security.Principal.GenericIdentity(username, "TokenAuth");
ClaimsIdentity identity = new ClaimsIdentity(claims);
string secret = ConfigurationManager.AppSettings["jwtSecret"].ToString();
var securityKey = new InMemorySymmetricSecurityKey(Encoding.Default.GetBytes(secret));
var signingCreds = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.HmacSha256Signature);
var securityToken = handler.CreateToken(
issuer: issuer,
audience: ConfigurationManager.AppSettings["UiUrl"].ToString(),
signingCredentials: signingCreds,
subject: identity,
expires: expires,
notBefore: DateTime.UtcNow
);
return handler.WriteToken(securityToken);
出于某种原因,即使过期时间设置为当前时间后10秒,当令牌被验证到大约5分钟时,它实际上不会引发异常。看到这个后,我想可能有5分钟的最低过期时间,所以我将过期时间设置为:
DateTime.UtcNow.AddMinutes(5);
然后,它将在10分钟后过期,但异常消息表示过期时间设置为应该的时间(用户登录后5分钟),当它在异常中显示当前时间时,则为过期时间后5分钟。所以,它似乎知道它应该在什么时候过期,但实际上直到过期时间过后5分钟才抛出异常。然后,由于令牌似乎在我设置的到期时间的基础上增加了5分钟,我将到期时间设置为:
DateTime.UtcNow.AddMinutes(-5).AddSecond(10);
我测试了这个,到目前为止它还没有过期(十多分钟后)。有人能解释一下为什么会这样,我做错了什么吗?此外,如果您看到我提供的代码中的任何其他内容,我们将不胜感激,因为我还不熟悉使用JWTs和这个库。
LifeTimeValidator似乎存在一些问题。只需使用自定义委托重写其逻辑即可。此外,还可以使用JWTBeareOptions类来控制身份验证中间件的行为。例如:
new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidIssuer = _configuration["Tokens:Issuer"],
ValidAudience = _configuration["Tokens:Audience"],
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
LifetimeValidator = LifetimeValidator,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"]))
}
}
并分配LifetimeValidotor委托,以提供自己的超时验证逻辑:
private bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken token, TokenValidationParameters @params)
{
if (expires != null)
{
return expires > DateTime.UtcNow;
}
return false;
}
通读@Denis Kucherov的答案后,我发现我可以使用他发布的相同自定义验证器,而无需使用JwtBearerOptions类,这需要我添加一个新库。
此外,由于有两个名称空间包含许多相同的类,我将确保提及所有这些都在使用该系统。识别模型。。。名称空间。(不是Microsoft.IdentityModels…)
以下是我最终使用的代码:
private bool CustomLifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken tokenToValidate, TokenValidationParameters @param)
{
if (expires != null)
{
return expires > DateTime.UtcNow;
}
return false;
}
private JwtSecurityToken ValidateJwtToken(string tokenString)
{
string secret = ConfigurationManager.AppSettings["jwtSecret"].ToString();
var securityKey = new InMemorySymmetricSecurityKey(Encoding.Default.GetBytes(secret));
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
TokenValidationParameters validation = new TokenValidationParameters()
{
ValidAudience = "MyAudience",
ValidIssuer = "MyIssuer",
ValidateIssuer = true,
ValidateLifetime = true,
LifetimeValidator = CustomLifetimeValidator,
RequireExpirationTime = true,
IssuerSigningKey = securityKey,
ValidateIssuerSigningKey = true,
};
SecurityToken token;
ClaimsPrincipal principal = handler.ValidateToken(tokenString, validation, out token);
return (JwtSecurityToken)token;
}
问题与ClockSkew
有关。通常,验证库(至少是MS库)会补偿时钟偏移<代码>时钟偏移默认值为5分钟。看到答案了吗
您可以在TokenValidationParameters
中更改ClockSkew
:
var tokenValidationParameters = new TokenValidationParameters
{
//...your setting
// set ClockSkew is zero
ClockSkew = TimeSpan.Zero
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters
});
快乐编码!
就在我以为我已经明白的时候...*叹息* 从我读到的关于立即的所有信息来看,我希望有以下几点: > 当尝试执行foo而不为输入字段提供值时,不会执行该操作,因为在期间发生错误,导致在此阶段之后直接重新呈现页面并显示错误消息。的值保持不变。(按预期工作) 当尝试do bar而不为输入字段提供值时,由于immediate属性,该操作将在期间执行。变量已更改。(按预期工作) “null返回值(作为act
我在Tomcat7中有一个web应用程序,它将会话中的用户信息作为DTO对象保存。我还为我的项目启用了Spring Security性,如果用户没有会话,它会自动将用户重定向到登录页面。 如果我登录到应用程序一次,然后在Eclipse中重新启动Tomcat,会发生的情况是,我的会话被冲出,但cookie没有运行。 Edit:尽管Firefox说,但如果关闭并重新启动Firefox,cookie仍然
问题内容: 我有一个会话验证过滤器,当会话过期时该过滤器注销用户。 这是一段代码,但是没有用。不起作用意味着即使会话过期,它也不会重定向到登录页面。 请帮助我解决此问题。 问题答案: 我有一个会话验证过滤器,当会话过期时该过滤器注销用户。 老实说,这完全没有道理。如果将已登录用户存储为会话的属性,并基于会话中已登录用户的存在来拦截“已登录”状态,则在任何时候都不需要手动注销该用户。会话已过期。当会
问题内容: 我正在尝试使用 BufferedReader 通过URL上的InputStreamReader 从Web文档中读取文本(到某些Apache服务器上的文件)。 现在,这很好。但是显然,我希望读者不要只读一行,而应该读文件中的所有行。 查看BufferedReader API,以下代码应做到这一点: 即在有更多行时读取所有行,在没有更多行时停止。但是,此代码不起作用-读者 永远不会 报告
问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮助。但是,在发送流数据时,等待A
问题内容: 在该类中,有两个字符串,和。 有什么不同?我什么时候应该使用另一个? 问题答案: 如果你的意思是和则: 用于在文件路径列表中分隔各个文件路径。考虑在上的环境变量。您使用a分隔文件路径,因此在上将是;。 是或用于拆分到特定文件的路径。例如在上,或