首页 > 解决方案 > 处理以前的 jwt 令牌,其中新的 jwt 令牌也为相同的凭证和安全性生成

问题描述

我在 dot net core 2.2 web API 中有应用程序,有 jwt 身份验证,还有过期日期

在这里,我对这个 jwt 令牌和 webapi 令牌库的安全性有一些疑问

1:在这里,我以前的 jwt 令牌与相同的重新登录(对于同一用户)有问题,这里令牌不同,但前一个在到期日之前也有效,所以我想知道如何处理以前的令牌这仍然有效,但为相同的 crandiantial 生成了一个新令牌

2:想要验证我的令牌来自受信任的来源(这里我还在我的 startup.cs 中添加了 CROS)。因此有任何更安全的方法来验证令牌命中来自受信任/验证(用户身份验证令牌)位置

3:我应该怎么做才能使我的令牌在(用户到服务器和服务器到用户端)上安全,比如使用 https SSL 认证

我需要一些建议以确保具有最佳安全性的 DOTNET CORE webapi

JWT 生成代码

 string BuildToken(int userId)
    {
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            _configuration["Jwt:Issuer"],
          _configuration["Jwt:Issuer"],
          new List<Claim> {
          new Claim(ClaimTypes.NameIdentifier , userId.ToString())
          },
          expires: GetExpireDate(),
          signingCredentials: creds);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

标签: .net.net-corejwtasp.net-core-2.2

解决方案


一旦生成了 JWT,它就会被认为是有效的,直到它的到期日期过去,或者签名变得无效。这是令牌“过期”的唯一方式。生成多个令牌是完全有效的。但是它们的寿命应该总是很短(几分钟),因为如果它们受到损害,任何人都可以使用它们。

处理这种情况的方法是使用刷新令牌。它们允许您在服务器上存储一个值,您可以使用该值启用/禁用为特定用户进一步重新发行令牌。

有关更完整的解释和示例,请查看此页面:http: //jasonwatmore.com/post/2018/08/14/aspnet-core-21-jwt-authentication-tutorial-with-example-api

第 2 点:所有通过 AuthHeader 进来的令牌都被考虑进行验证。NetCore 中的验证会根据您在配置 JWT 时应用的配置自动进行。

因此,您的令牌验证配置如下:

public void ConfigureServices(IServiceCollection services)
{
     // configure jwt authentication
     var appSettings = appSettingsSection.Get<AppSettings>();
     var key = Encoding.ASCII.GetBytes(appSettings.Secret);
     services.AddAuthentication(x =>
     {
         x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
         x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
     })
     .AddJwtBearer(x =>
     {
         x.RequireHttpsMetadata = false;
         x.SaveToken = true;
         x.TokenValidationParameters = new TokenValidationParameters
         {
             ValidateIssuerSigningKey = true,
             IssuerSigningKey = new SymmetricSecurityKey(key),
             ValidateIssuer = false,
             ValidateAudience = false
         };
     });
}

在您的应用程序启动中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseCors(x => x
       .AllowAnyOrigin()
       .AllowAnyMethod()
       .AllowAnyHeader());

    **app.UseAuthentication();**
    app.UseMvc();
}

最后,您需要将 [Authorize] 属性应用于您的控制器,如下所示:

**[Authorize]**
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
}

基本思想是您在“登录”方法中“创建”令牌并将其返回给调用者 - 然后将相同的令牌从客户端传递回您的服务。如果令牌是使用与设置 ConfigureServices 方法相同的设置创建的,它会被中间件读取并应用于 HttpContext 上的 User 属性,如下所示:

public Controller(IHttpContextAccessor httpContextAccessor)
{
    var userId = HttpContextAccessor.HttpContext.User;
}

如果令牌被拒绝,401 的 HttpStatus 代码将自动发送回调用方,并显示“未授权”消息

第 3 点:是的,正确保护 JWT 令牌本身的最佳且可能唯一的方法是真正使用 HTTPS。令牌的“签名”组件不能保护它或防止它被欺诈性使用;它只是提供了一种确保它未被篡改的方法


推荐阅读