准备工作:在步入正题之前我们首先要对JWT加密有个初步的概念和认识,并对其原理有一定的理解,这样才能使我们在.Net 6.0中更快的上手JWT加密,下面是我整理JWT加密的一些资料,各位看官请坐!
JWT(JSON Web Token)是一种基于 JSON 的轻量级身份验证和授权的规范,通过三部分组成:头部、载荷和签名进行加密。
头部: JWT 头部通常由两部分组成,一是声明类型,即 JWT,二是声明加密算法,比如 HS256、RS256 等。头部采用 Base64Url 编码,不加密。
载荷: JWT 载荷是 JWT 的主要内容,一般由一些声明和用户自定义的数据组成,这些声明包括用户 ID、过期时间、权限等。载荷同样采用 Base64Url 编码,不加密。
签名: JWT 签名是对头部和载荷进行加密生成的,用于验证 JWT 的合法性。签名需要使用头部中指定的加密算法和密钥进行计算,通常使用 HMAC 或者 RSA 算法。签名的计算过程如下:
- 将头部和载荷组成一个字符串,中间用 . 分隔。
- 使用头部中指定的加密算法和密钥对该字符串进行加密生成签名。
- 将签名加入到 JWT 中,形成最终的 JWT。
在验证 JWT 时,需要使用同样的密钥和算法对头部和载荷进行验证,验证通过即表示 JWT 是合法的,否则是无效的。
总的来说,JWT 加密原理就是通过将头部和载荷进行 Base64Url 编码,然后使用指定的加密算法和密钥对其进行加密生成签名,最后将签名加入到 JWT 中。在验证 JWT 时,需要使用同样的密钥和算法对头部和载荷进行验证,以判断 JWT 是否有效。
1.首先需要安装JWT的NuGet包
1 Microsoft.AspNetCore.Authentication.JwtBearer
2.在appsettings.json文件中配置,并创建对应的类
1 //JWT加密 2 "TokenPotions": { 3 "SecretKey": "Uw5EKn31spRlxGsK", 4 "Issuer": "域名", 5 "Audience": "simple", 6 "ExpireMinutes": 240 7 }
1 /// <summary> 2 /// Tonken配置文件类 3 /// </summary> 4 public class TokenPotions 5 { 6 /// <summary> 7 /// 密钥 8 /// </summary> 9 public string? SecretKey { get; set; } 10 11 /// <summary> 12 /// 发行人 13 /// </summary> 14 public string? Issuer { get; set; } 15 16 /// <summary> 17 /// 拥护者 18 /// </summary> 19 public string? Audience { get; set; } 20 21 /// <summary> 22 /// 过期时间分钟 23 /// </summary> 24 public int ExpireMinutes { get; set; } 25 }
3.在Program中配置JWT,Swagger,跨域处理
#region JWT加密 var configuration = services.BuildServiceProvider().GetRequiredService<IConfiguration>(); var tokenSection = configuration.GetSection(nameof(TokenPotions)); services.Configure<TokenPotions>(tokenSection); var tokenOptions = tokenSection.Get<TokenPotions>(); //注入jwt services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidateIssuer = true,//是否在令牌期间验证签发者 ValidateAudience = true,//是否验证接收者 ValidateLifetime = true,//是否验证失效时间 ValidateIssuerSigningKey = true,//是否验证签名 ValidIssuer = tokenOptions.Issuer,//签发者, 签发token的人 ValidAudience = tokenOptions.Audience,//接收者 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecretKey!))//密钥 }; }); #endregion //注入Swagger builder.Services.AddSwaggerGen(options => { options.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference=new OpenApiReference{Id="Bearer",Type=ReferenceType.SecurityScheme}, }, Array.Empty<string>() } }); options.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme { Description = "请输入文字'Bearer '后面跟空格和token格式 Bearer {token}", Name = "Authorization", In = Microsoft.OpenApi.Models.ParameterLocation.Header, Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey }); }); //配置跨域 builder.Services.AddCors(policy => { policy.AddPolicy("CorsPolicy", opt => opt .AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod() .WithExposedHeaders("X-Pagination")); });
4.使用跨域和鉴权的中间件
1 app.UseCors("CorsPolicy");//跨域 2 3 app.UseAuthentication();//在前 鉴权 4 5 app.UseAuthorization();//在后 授权
5.登录时往JWT中添入对应的角色,并生成Token响应给前端,并写入请求头
1 /// <summary> 2 /// 登录 3 /// </summary> 4 /// <param name="paraDto">参数dto</param> 5 /// <returns></returns> 6 [HttpPost("Login")] 7 public ActionTResult Login([FromBody] LoginWebDto paraDto) 8 { 9 ActionTResult apiResult = new ActionTResult(); 10 try 11 { 12 var user = _sysUserWebBL.CheckLogin(paraDto);//验证登录 13 if (user != null) 14 { 15 var claims = new[] 16 { 17 new Claim(ClaimTypes.Role,user.Role.ToString())//写入用户角色 18 }; 19 var cred = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenPotions.SecretKey!)), SecurityAlgorithms.HmacSha256); 20 //令牌 21 var jwtSecurityToken = new JwtSecurityToken 22 ( 23 _tokenPotions.Issuer,//签发者 24 _tokenPotions.Audience,//接收者 25 claims,//payload 26 expires: DateTime.Now.AddMinutes(_tokenPotions.ExpireMinutes),//过期时间 27 signingCredentials: cred 28 ); 29 var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); 30 user.Token = token; 31 apiResult.Data = user; 32 } 33 } 34 catch (Exception ex) 35 { 36 apiResult.ErrorMsg = ex.Message; 37 apiResult.Succes = SuccessTypeEnum.Error; 38 } 39 return apiResult; 40 }
6.测试,我们使用测试接口并指定只有Admin(超级管理员)身份才能看
下面我们可以看到,因为我们刚刚登录的用户是普通用户的身份,是无法访问接口的,下面也返回了403表示权限不足
好了今天这节到这里就结束了,因为工作比较忙,这篇写的比较仓促,很多细节没有讲到位,不过跟着本章节一步一步来,还是可以实现JWT加密的,如果有疑问或者发现不足的地方也欢迎各位在面评论探讨哦!
本文来自博客园,作者:沈威,转载请注明原文链接:https://www.cnblogs.com/shenweif/p/17239310.html
标签:加密,验证,JWT,签名,6.0,var,new,Net From: https://www.cnblogs.com/wl-blog/p/17261031.html