我在我的ASP.NET Core2WebAPI项目中使用JWT令牌
我的前端web客户端发送一个JWT令牌,它最初是从Web登录API获得的,每个请求都正常工作。不过,我还有一个离线客户端,它使用相同的API,最初在线登录,然后存储JWT脱机,只有在用户同步应用程序时才发送它,这可能会在一周后。令牌可能已经过期,或者服务器web应用程序在规定的时间内重新启动。
如果JWT令牌由于离线客户端过期而失败,我仍然希望命中Web控制器方法并填充ASP.NET Identity User
对象,因为我需要用户名。我将记录这个事件,但我也需要来自过期/无效令牌的用户名。当前,如果身份验证失败,控制器方法将不会被输入,因此我添加了一个AllowAnonymous属性,但是这将导致User.Identity为空,因为我需要用户名
我的代码:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication()
.AddJwtBearer(cfg =>
{
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = _config["Tokens:Issuer"],
ValidAudience = _config["Tokens:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]))
};
});
当用户登录时
private IActionResult CreateToken(ApplicationUser user, IList<string> roles)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
_config["Tokens:Issuer"],
_config["Tokens:Audience"],
claims.ToArray(),
expires: DateTime.Now.AddMinutes(60),
signingCredentials: creds);
var results = new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo,
};
return Created("", results);
我确保在对各种API调用进行身份验证之后,传递JWT令牌。
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class MyController : Controller
{
这允许我为各种API调用捕获登录用户的以下代码
var loggedInUser = User.Identity.Name;
如果用户名已过期或无效,如何从JWT令牌读取用户名?
发布于 2018-02-09 10:43:55
如果您希望授权通过,即使令牌已经过期,您可以简单地通过将它添加到TokenValidationParameters
来禁用生存期验证
services.AddAuthentication()
.AddJwtBearer(cfg =>
{
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = _config["Tokens:Issuer"],
ValidAudience = _config["Tokens:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]))
//Do not check the expiry of token
ValidateLifetime = false,
};
});
这将确保授权中间件认为令牌是有效的,并在MVC中间件中填充User.Identity
对象。
然而,此检查也将禁用您的web客户端的过期检查。您必须确定适当的客户端(不能确定),并在控制器中检查是否过期。
一个更好的方法是看一个更好的设计来解决你的基本需求。
令牌可能已经过期,或者服务器web应用程序在规定的时间内重新启动。
我对这句话有点困惑。如果服务器web应用程序在平均时间内重新启动,并且遇到令牌过期,我假设您正在使用临时签名密钥对JWT令牌进行签名。您应该切换到使用永久签名密钥。
对于脱机客户端(您想要长寿令牌),请查看刷新令牌。刷新令牌通常具有较长的生存期,可用于为较新的访问令牌进行交换。当指定范围offline_access
时,标准的oauth2.0实现会发出刷新令牌。作用域的名称应该指示刷新令牌的通用用例。
您可以将web客户端和脱机客户端配置为您的Authority Server上的两个不同客户端,从而确保只向脱机客户端发出刷新令牌。
https://stackoverflow.com/questions/48707281
复制