.NET Core JWT详解

JWT(Json Web Token)是一种跨域的身份验证解决方案,它可以在网络上安全地传输数据,用于在API之间进行身份验证和授权。在.NET Core中,可以使用Microsoft.AspNetCore.Authentication.JwtBearer包来轻松地添加JWT身份验证。本文将对.NET Core中的JWT进行详细介绍,涵盖以下主题:

一、安装和配置JWT

在.NET Core中使用JWT需要安装Microsoft.AspNetCore.Authentication.JwtBearer包。在项目中通过nuget包管理器或命令行中运行以下命令来安装:

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

安装后,在Startup.cs文件中的ConfigureServices方法中添加以下代码:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = Configuration["Jwt:Issuer"],
        ValidAudience = Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
    };
});

该配置代码将使.NET Core应用程序支持JWT身份验证。首先,AddAuthentication方法设置JwtBearerDefaults身份验证方案,这意味着授权策略将使用JWTBearerAuthenticationOptions类中的设置,JwtBearerDefaults身份验证方案提供默认的jwt身份验证选项。然后JwtBearer身份验证选项分配了一个新的TokenValidationParameters实例,该实例定义了JWT识别配置的设置。例如,Validators被设置为true以执行身份验证,ValidIssuer和ValidAudience设置为数据流需要进行身份验证和签名才能接受的发行方和受众设置。最后,IssuerSigningKey被设置为应用的加密密钥。

二、生成Token

生成JWT token对身份验证和授权的有效性很重要,因为它使用户可以访问其资源和权限。在.NET Core中,可以使用以下代码生成JWT token:

public string GenerateToken(User user)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(Configuration["Jwt:SecretKey"]);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            new Claim(ClaimTypes.Name, user.Username),
            new Claim(ClaimTypes.Email, user.Email)
        }),
        Expires = DateTime.UtcNow.AddDays(7),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
            SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

上面的代码将生成一个包含数据 and claims的JWT token。通过句柄类JwtSecurityTokenHandler将数据进行序列化操作,生成一个包含所有有效数据的JWT token。密钥key的值是加密token内容的密钥,Expires配置JWT tokens的有效截止日期,SymmetricSecurityKey将密钥和SHA-256签名算法用于生成签名。

三、使用JWT

在进行身份验证时,首先需要从传入的请求中提取JWT token,如下所示:

var authHeader = context.HttpContext.Request.Headers["Authorization"].FirstOrDefault();
var token = authHeader?.Split(" ").Last();

一旦获取token后,需要进行身份验证。使用以下代码进行验证:

var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(Configuration["Jwt:SecretKey"]);
try
{
    var tokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = true,
        ValidIssuer = Configuration["Jwt:Issuer"],
        ValidateAudience = true,
        ValidAudience = Configuration["Jwt:Audience"],
        ValidateLifetime = true,
    };
    SecurityToken validatedToken;
    var claimsPrincipal = tokenHandler.ValidateToken(token, tokenValidationParameters, out validatedToken);
    context.HttpContext.User = claimsPrincipal;
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
}

在上面的代码中,我们使用了ValidateToken方法来验证token的有效性。TokenValidationParameters对象定义了一些可能用于配置来自哪些发行者和受众验证令牌的属性,令牌是否过期,签名是否有效等。如果令牌验证成功,将进行授权并返回用户(ClaimsPrincipal对象),失败将提示异常。

四、Token刷新

由于JWT tokens具有有效期的限制,为了避免过期问题,需要定期刷新accessToken。通过使用以下代码来轻松处理JWT tokens的期限:

private async Task RefreshToken(string token, string refreshToken)
{
    var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(Configuration["Jwt:SecretKey"]);
    
    try
    {
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidateAudience = true,
            ValidAudience = Configuration["Jwt:Audience"],
            ValidateLifetime = false
        };
        SecurityToken validatedToken;
        var claimsPrincipal = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out validatedToken);
        if (validatedToken is JwtSecurityToken jwtSecurityToken && jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
        {
            var username = claimsPrincipal.Identity.Name;
            var user = await _userManager.FindByNameAsync(username);
            if (user == null)
            {
                return null;
            }

            var isValidated = await _userManager.CheckPasswordAsync(user, refreshToken);
            if (!isValidated)
            {
                return null;
            }

            var newToken = GenerateToken(user);
            return newToken;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

    return null;
}

在上面的代码中,我们通过传递原始token和refreshToken验证当前token是否过期,如果过期则通过GenerateToken方法生成新的token。与上一小节代码的不同之处在于,这里将ValidateLifetime设置为false,以便控制时间间隔并在过期时生成新token。

五、Token吊销

在某些情况下,我们可能需要吊销某个用户的token。为了实现这个功能,我们必须通过添加一个吊销列表,以记录已被吊销的token。从而验证token时可以在吊销列表中搜索。将吊销列表添加到代码中的步骤如下:

首先,需要添加一个TokenRevocationList和RefreshToken实体类。TokenRevocationList实体类包含一个Id字段和一个Revoked字段,而RefreshToken实体类包含一个Id和一个RefreshToken字段。

public class TokenRevocationList
{
    public int Id { get; set; }
    public string Token { get; set; }       
    public DateTime Revoked { get; set; }
}

public class RefreshToken
{
    public int Id { get; set; }
    public string Token { get; set; }
    public DateTime Expires { get; set; }
}

然后,需要在Startup类中的ConfigureServices方法中配置DbContext,如下所示:

services.AddDbContext<YourDbContext>(options => options.UseSqlServer(Configuration["ConnectionString"]));

在进行身份验证时,通过以下代码添加TokenRevocationList检查:

var tokenRevocationList = _context.TokenRevocationList.ToList();
if (tokenRevocationList.Any(x => x.Token == token))
{
    throw new SecurityTokenException("This token has been revoked");
}

最后,在注销时将token添加到TokenRevocationList以吊销token:

var tokenRevocationList = new TokenRevocationList
{
    Token = token,
    Revoked = DateTime.UtcNow
};

await _context.AddAsync(tokenRevocationList);
await _context.SaveChangesAsync();

结束语

本文介绍了.NET Core中使用JWT进行身份验证的步骤。通过安装并配置JWT包,生成token,使用token进行身份验证,刷新token并吊销token实现了应用程序的安全授权。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/288816.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-12-24 03:00
下一篇 2024-12-24 03:00

相关推荐

  • 解决.net 6.0运行闪退的方法

    如果你正在使用.net 6.0开发应用程序,可能会遇到程序闪退的情况。这篇文章将从多个方面为你解决这个问题。 一、代码问题 代码问题是导致.net 6.0程序闪退的主要原因之一。首…

    编程 2025-04-29
  • JWT验证Token的实现

    本文将从以下几个方面对JWT验证Token进行详细的阐述,包括:JWT概述、JWT验证Token的意义、JWT验证Token的过程、JWT验证Token的代码实现、JWT验证Tok…

    编程 2025-04-29
  • JWT String Argument Cannot Be Null or Empty

    JWT(JSON Web Token)是一种用于进行身份验证的标准。在使用JWT时,经常会遇到“JWT String Argument Cannot Be Null or Empt…

    编程 2025-04-27
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • 详解eclipse设置

    一、安装与基础设置 1、下载eclipse并进行安装。 2、打开eclipse,选择对应的工作空间路径。 File -> Switch Workspace -> [选择…

    编程 2025-04-25
  • C语言贪吃蛇详解

    一、数据结构和算法 C语言贪吃蛇主要运用了以下数据结构和算法: 1. 链表 typedef struct body { int x; int y; struct body *nex…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25

发表回复

登录后才能评论