我在ASP.NET Core 2 Web API项目中使用JWT令牌
我的前端Web客户端发送最初从Web API登录API获取的JWT令牌,每个请求都正常工作。但是我也有一个离线客户端,它使用相同的API并且最初在线登录,然后将JWT离线存储,只有当用户同步应用程序时才会发送,这可能是一周之后。令牌可能已过期或服务器Web应用程序在平均时间内重新启动。
如果JWT令牌因脱机客户端过期而失败,我仍然希望命中Web API控制器方法,并填充ASP.NET Identity User
对象,因为我需要用户名。我将记录此事件,但我也需要来自过期/无效令牌的用户名。目前,如果身份验证失败,则不会输入控制器方法,因此我添加了[AllowAnonymous]属性,但这会导致User.Identity为null,因为我想要用户名
我的代码:
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令牌的用户名已过期或无效,我如何阅读该用户名?
答案 0 :(得分:1)
如果您希望授权即使令牌已过期也可以通过,您可以通过将生命周期验证添加到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应用程序在平均时间内重新启动并且您遇到令牌到期,我假设您正在使用临时签名密钥来签署JWT令牌。您应该切换到使用永久签名密钥。
对于您需要长期令牌的脱机客户端,请查看刷新令牌。刷新令牌通常具有更长的生命周期,可用于交换更新的访问令牌。指定范围offline_access
时,标准oauth2.0实现问题刷新令牌。范围名称应指示刷新令牌的常见用例。
您可以将Web客户端和脱机客户端配置为Authority Server上的两个不同客户端,从而确保仅向脱机客户端发出刷新令牌。