Asp.net core使用Authentication使用jwt简单登录认证
研究了两天,简单使用就这些,如果需要token续期或者刷新或者自定义校验处理需要重写比较麻烦。
在controller中单独获取请求头可使用
HttpContext.Request.Headers["Authorization"]
使用流程是:先认证登录 -> 再校验权限
Authentication -> Authorization
- 安装依赖,.net8版本为例
- Microsoft.AspNetCore.Authentication.JwtBearer
- Newtonsoft.Json
- 配置jwt所需配置,再appsettings.json文件
"Jwt": { "SecretKey": "U2FsdGVkX1/52fw3vL3OY4F1H7BV12pjPPb1mUhZyEPVRk72S5X2z/A8V9lTvK6T", "Issuer": "WebAppIssuer", "Audience": "WebAppAudience", "Expire": 30000 }
- jwt生成或解析帮助类 JwtHelper
using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; namespace jwt_api.Helper; public class JwtHelper { private readonly IConfiguration _configuration; public JwtHelper(IConfiguration configuration) { _configuration = configuration; } public string CreateToken(string Name, int id) { // 1. 定义需要使用到的Claims var claims = new[] { new Claim(ClaimTypes.Name, "u_admin"), //HttpContext.User.Identity.Name new Claim("Id", id.ToString()), new Claim("Name", Name) }; // 2. 从 appsettings.json 中读取SecretKey var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"])); // 3. 选择加密算法 var algorithm = SecurityAlgorithms.HmacSha256Signature; // 4. 生成Credentials var signingCredentials = new SigningCredentials(secretKey, algorithm); // 5. 根据以上,生成token var jwtSecurityToken = new JwtSecurityToken( _configuration["Jwt:Issuer"], //Issuer _configuration["Jwt:Audience"], //Audience claims, //Claims, DateTime.Now, //notBefore DateTime.Now.AddSeconds(Convert.ToInt32(_configuration["Jwt:Expire"])), //expires signingCredentials //Credentials ); // 6. 将token变为string var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); return token; } }
- 主程序编写 Program.cs
using System.Text; using jwt_api.Helper; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); #region 配置登录认证 var configuration = builder.Configuration; // 配置登录认证 builder.Services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, //是否验证Issuer ValidIssuer = configuration["Jwt:Issuer"], //发行人Issuer ValidateAudience = true, //是否验证Audience ValidAudience = configuration["Jwt:Audience"], //订阅人Audience ValidateIssuerSigningKey = true, //是否验证SecurityKey IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"])), //SecurityKey ValidateLifetime = true, //是否验证失效时间 ClockSkew = TimeSpan.FromSeconds(30), //过期时间容错值,解决服务器端时间不同步问题(秒) RequireExpirationTime = true, }; // 当token验证通过后(执行完 JwtBearerEvents.TokenValidated 后), // 是否将token存储在 Microsoft.AspNetCore.Authentication.AuthenticationProperties 中 // 默认 true options.SaveToken = true; options.Events = new JwtBearerEvents { //此处为权限验证失败后触发的事件 OnChallenge = context => { //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦,必须 context.HandleResponse(); //自定义自己想要返回的数据结果,我这里要返回的是Json对象,通过引用Newtonsoft.Json库进行转换 var payload = JsonConvert.SerializeObject(new { Code = "401", Message = "很抱歉,您无权访问该接口;请登录!" }); //自定义返回的数据类型 context.Response.ContentType = "application/json"; //自定义返回状态码,默认为401 我这里改成 200 context.Response.StatusCode = StatusCodes.Status200OK; //输出Json数据结果 context.Response.WriteAsync(payload); return Task.FromResult(0); } }; }); // 添加一个生成jwt和解析帮助类 builder.Services.AddSingleton<JwtHelper>(); #endregion builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); #region 启用认证 app.UseAuthentication(); app.UseAuthorization(); #endregion app.MapControllers(); /*app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret") .RequireAuthorization();*/ app.Run();
- 编写测试请求
- 测试结果
- 使用1接口获取token,再测试2接口成功结果
- 失败结果如下