ASP.NETCore-中间件Middleware(六)_认证+授权中间件-JWT
先随便贴点代码
1、引用JwtBearer Nuget包
2、Program.cs启用JWT
using fly_chat1_net7.Middlewares;
using fly_chat1_net7.Middlewares.UserLoginAuthorizations;
using fly_webapi.IService.UserService.LoginAuthorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.CookiePolicy;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Net.Http;
using System.Text;
using System.Threading;
namespace fly_chat1_net7
{
public class Program
{
public static void Main(string[] args)
{
// try前也可能报错,但是错误是可控的。实际项目中使用时可以再加个try,只记录日志到文件中。
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) // 设置“configuration”的查找目录为程序目录
.AddJsonFile("appsettings.json") // 设置“configuration”的读取文件
.Build(); // 获取配置
var builder = WebApplication.CreateBuilder(args);
// 中间件知识https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-6.0#order
#region 容器Services
builder.Services.AddControllers(); // 添加Controller
builder.Services.AddHttpContextAccessor(); // 操作Http上下文;比如:AOP里面可以获取IOC对象
builder.Services.AddEndpointsApiExplorer(); // ASP.NET Core自身提供;Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
#region JWT
IUserAuthorization userAuthorization = new UserAuthorization_JWT();
builder.Services.AddSingleton(userAuthorization); // JWT认证中间件
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => { // 配置Authentication用的JWT
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidIssuer = configuration["Jwt:Issuer"],
ValidAudience = configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecurityKey"] ?? "a48fafeefd334237c2ca207e842afe0b")),
ClockSkew = TimeSpan.Zero
};
});
#endregion JWT
#endregion 容器Services
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles(); // 在UseRouting()前
app.UseRouting();
app.UseAuthentication(); // 认证
app.UseAuthorization(); // 授权
app.MapControllers();
app.Run();
}
}
}
3、JWT的配置(appsettings.json中)
{
"Jwt": {
"Issuer": "yunyistars.com", // token 的颁发者
"Audience": "yunyistars.com", // token 的接收者
"SecurityKey": "a48fafeefd334237c2ca207e842afe0b", // 加密 token的key值(32位)
"ExpireMinutes": "20" // token 的过期时间(单位分钟)
},
}
4、JWT登录认证中间件
using fly_webapi.IService.UserService.LoginAuthorization;
using fly_webapi.ViewModel.Users;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Security.Claims;
using System.Text;
namespace fly_chat1_net7.Middlewares.UserLoginAuthorizations
{
/// <summary>
/// 用户认证_JWT
/// </summary>
public class UserAuthorization_JWT : IUserAuthorization
{
/// <summary>
/// 配置文件
/// </summary>
IConfigurationRoot _configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) // 设置“configuration”的查找目录为程序目录
.AddJsonFile("appsettings.json") // 设置“configuration”的读取文件
.Build(); // 获取配置
/// <summary>
/// 生成用户信息-创建Token
/// 从JWT中读取信息var name = HttpContext.User.FindFirst(JwtRegisteredClaimNames.Name)?.Value;
/// </summary>
/// <param name="userInfoVModel">用户信息</param>
public AuthorizationObject Create(UserInfoVModel userInfoVModel)
{
DateTime expiresAt = DateTime.UtcNow.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpireMinutes"])); // token 的过期时间
// 签发一个加密后的用户信息凭证ClaimsPrincipal,用来标识用户的身份
IEnumerable<Claim> claims = new Claim[] { // 将用户信息添加到 Claim 中
new Claim(ClaimTypes.Name,userInfoVModel.UserName), // 用户名
new Claim(ClaimTypes.Role,userInfoVModel.RoleId.ToString()), // 角色ID
new Claim(ClaimTypes.MobilePhone,userInfoVModel.MobilePhone), // 手机号
new Claim(ClaimTypes.Email,userInfoVModel.Email), // 邮箱号
new Claim(ClaimTypes.Expiration,expiresAt.ToString()) // 过期日期
};
//var identity = new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme);
//_httpContextAccessor.HttpContext.SignInAsync(JwtBearerDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
// 设置 SecurityTokenDescriptor
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecurityKey"] ?? "a48fafeefd334237c2ca207e842afe0b")); // 加密 token 的key值
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims), // 用户信息
Issuer = _configuration["Jwt:Issuer"], // Jwt token 的签发者
Audience = _configuration["Jwt:Audience"], // Jwt token 的接收者
Expires = expiresAt, // 过期时间
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256), //创建 token
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor); // 创建Token
//存储 Token 信息
var jwt = new AuthorizationObject
{
//UserId = userInfoVModel.UserId, // 用户的Id
AuthorizationType=AuthorizationObjectType.Jwt_Microsoft, // AuthorizationObject类型为Jwt_Microsoft
Token = tokenHandler.WriteToken(token), // 获取创建完的Token
Expiration= expiresAt // 过期时间
};
// 把Token存放到MemoryCache或Redis中
return jwt;
}
/// <summary>
/// 停用Token
/// </summary>
/// <param name="token">Token</param>
/// <returns></returns>
public async Task<bool> DeactivateAsync(string token)
{
// 修改Token信息
// 把Token从MemoryCache或Redis中删除
return true;
}
/// <summary>
/// 停用当前Token
/// </summary>
/// <param name="token">Token</param>
/// <returns></returns>
public async Task<bool> DeactivateCurrentAsync(HttpContext httpContext) => await DeactivateAsync(GetCurrentAsync(httpContext));
/// <summary>
/// 刷新 Token
/// </summary>
/// <param name="token">Token</param>
/// <param name="dto">用户信息数据传输对象</param>
/// <returns></returns>
public async Task<AuthorizationObject> RefreshAsync(string token, UserInfoVModel userInfoVModel)
{
var jwtOld =await IsActiveAsync(token); // 判断 Token 是否有效
if (!jwtOld)
{
throw new Exception("未获取到当前用户信息!");
}
// 将旧的Token从MemoryCache或Redis中删除
var jwt = Create(userInfoVModel);
// 将新的Token存放到MemoryCache或Redis中
return jwt;
}
/// <summary>
/// 判断 Token 是否有效
/// </summary>
/// <param name="token">Token</param>
/// <returns></returns>
public async Task<bool> IsActiveAsync(string token)
{
// 检验1-Token是否有效(Token格式正常+未过期)
// 检验2-MemoryCache或Redis中是否存在(可以防伪造Token)
return true;
}
/// <summary>
/// 判断当前 Token 是否有效
/// </summary>
/// <returns></returns>
public async Task<bool> IsActiveCurrentAsync(HttpContext httpContext)=> await IsActiveAsync(GetCurrentAsync(httpContext));
#region private方法
/// <summary>
/// 获取 HTTP 请求的 Token 值
/// </summary>
/// <returns></returns>
private string GetCurrentAsync(HttpContext httpContext)
{
//http header
var authorizationHeader = httpContext.Request.Headers["authorization"];
//token
return authorizationHeader == StringValues.Empty? string.Empty: authorizationHeader.Single().Split(" ").Last(); // bearer tokenvalue
}
#endregion private方法
}
}
本文来自博客园,作者:꧁执笔小白꧂,转载请注明原文链接:https://www.cnblogs.com/qq2806933146xiaobai/articles/17465637.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
2021-06-08 JS 倒计时弹窗