using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SqlSugar; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using WIDESEA_Core.Authorization; using WIDESEA_Core.Const; using WIDESEA_Core.DB; using WIDESEA_Core.Extensions; using WIDESEA_Core.Helper; using WIDESEA_Core.Seed; using ICacheService = WIDESEA_Core.Caches.ICacheService; namespace WIDESEA_Core.HttpContextUser { /// /// 提供基于ASP.NET Core HttpContext的用户信息访问服务 /// /// /// 实现IUser接口,通过JWT Token解析用户身份信息, /// 包括用户名、用户ID、租户ID、角色ID等核心属性, /// 并提供Token管理、身份验证和声明信息获取等功能 /// public class AspNetUser : IUser { private readonly IHttpContextAccessor _accessor; private readonly ICacheService _cacheService; //private readonly ILogger _logger; public AspNetUser(IHttpContextAccessor accessor, ICacheService cacheService) { _accessor = accessor; _cacheService = cacheService; /*_logger = logger;*/ } /// /// 获取当前用户的用户名(从JWT Token中解析) /// /// 用户名字符串,若不存在则返回空字符串 public string UserName => GetUserInfoFromToken(ClaimTypes.Name).FirstOrDefault() ?? ""; /// /// 获取当前用户的ID,从JWT令牌的JTI声明中解析。若声明不存在或解析失败则返回0。 /// /// 用户ID(整数) public int UserId => GetClaimValueByType(JwtRegisteredClaimNames.Jti) == null ? 0 : GetClaimValueByType(JwtRegisteredClaimNames.Jti).FirstOrDefault()?.ObjToInt() ?? 0; /// /// 从用户令牌中获取租户ID /// /// 当前用户的租户ID,若获取失败则返回-1 public long TenantId => GetUserInfoFromToken(nameof(TenantId)).FirstOrDefault()?.ObjToLong() ?? -1; /// /// 获取当前用户角色ID(从Token中解析) /// /// 角色ID,若不存在则返回0 public int RoleId => GetUserInfoFromToken(ClaimTypes.Role).FirstOrDefault()?.ObjToInt() ?? 0; /// /// 获取当前用户的Token /// public string Token => GetToken(); /// /// 获取菜单类型,根据请求头中是否包含"uniapp"标识返回1或0 /// public int MenuType => (_accessor.HttpContext?.Request.Headers.ContainsKey("uniapp") ?? false) ? 1 : 0; /// /// 检查当前HTTP上下文用户是否已认证 /// /// 如果用户已认证返回true,否则返回false public bool IsAuthenticated() { return _accessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false; } /// /// 获取当前用户的JWT Token /// /// /// 返回当前请求的Authorization头中的Bearer Token, /// 如果请求来自Swagger且验证成功则返回Swagger的JWT Token, /// 否则尝试从缓存中获取用户Token /// /// /// 1. 优先从请求头Authorization中获取Bearer Token /// 2. 如果是Swagger请求且验证成功,使用Swagger的JWT Token /// 3. 最后尝试从缓存中获取用户Token /// public string GetToken() { string token = _accessor.HttpContext?.Request?.Headers["Authorization"].ObjToString().Replace("Bearer ", "") ?? ""; if (!token.IsNullOrEmpty()) { return token; } if (_accessor.HttpContext?.IsSuccessSwagger() == true) { token = _accessor.HttpContext.GetSuccessSwaggerJwt(); if (token.IsNotEmptyOrNull()) { //UserInfo userInfo = JwtHelper.SerializeJwt(token); //if (userInfo.UserId > 0) //{ // return token; //} List claims1 = _accessor.HttpContext.User.Claims.ToList(); if (_accessor.HttpContext.User.Claims.Any(s => s.Type == JwtRegisteredClaimNames.Jti)) { return token; } var claims = new ClaimsIdentity(GetClaimsIdentity(token)); _accessor.HttpContext.User.AddIdentity(claims); return token; } } token = _cacheService.Get(UserId.ToString()); if (!string.IsNullOrEmpty(token)) { return token; } return token; // string token = _cacheService.Get(UserId.ToString()); //if (!string.IsNullOrEmpty(token)) { return token; } //return string.Empty; //return _accessor.HttpContext?.Request?.Headers["Authorization"].ObjToString().Replace("Bearer ", "") ?? ""; } /// /// 更新用户令牌 /// /// 新的令牌字符串 /// /// 该方法会将用户ID与令牌关联存储到缓存服务中 /// public void UpdateToke(string token) { _cacheService.AddOrUpdate(UserId.ToString(), token); } /// /// 获取一个值,指示当前用户是否为超级管理员 /// /// /// 通过检查角色ID是否为超级管理员角色来判断 /// public bool IsSuperAdmin => IsRoleIdSuperAdmin(RoleId); /// /// 从JWT令牌中获取指定类型的用户声明信息 /// /// 要获取的声明类型 /// 包含声明值的字符串列表,若令牌无效或未找到声明则返回空列表 public List GetUserInfoFromToken(string ClaimType) { var jwtHandler = new JwtSecurityTokenHandler(); var token = ""; token = GetToken(); // token校验 if (token.IsNotEmptyOrNull() && jwtHandler.CanReadToken(token)) { JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(token); List items = (from item in jwtToken.Claims where item.Type == ClaimType select item.Value).ToList(); return items; } return new List() { }; } /// /// 获取当前HTTP上下文的身份声明集合,包括请求头信息 /// /// 包含当前用户声明和请求头信息的集合,若HttpContext为空则返回空集合 public IEnumerable GetClaimsIdentity() { if (_accessor.HttpContext != null) { var claims = _accessor.HttpContext.User.Claims.ToList(); var headers = _accessor.HttpContext.Request.Headers; foreach (var header in headers) { claims.Add(new Claim(header.Key, header.Value)); } return claims; } return ArraySegment.Empty; } /// /// 从JWT令牌中获取身份声明(Claims) /// /// JWT令牌字符串 /// 包含声明信息的集合,若令牌无效则返回空集合 public IEnumerable GetClaimsIdentity(string token) { var jwtHandler = new JwtSecurityTokenHandler(); // token校验 if (token.IsNotEmptyOrNull() && jwtHandler.CanReadToken(token)) { var jwtToken = jwtHandler.ReadJwtToken(token); return jwtToken.Claims; } return new List(); } /// /// 根据声明类型获取对应的声明值列表 /// /// 要查询的声明类型 /// 匹配指定类型的声明值列表 public List GetClaimValueByType(string ClaimType) { return (from item in GetClaimsIdentity() where item.Type == ClaimType select item.Value).ToList(); } /// /// 检查角色ID是否为超级管理员 /// /// 要检查的角色ID /// 如果是超级管理员返回true,否则返回false public bool IsRoleIdSuperAdmin(int roleId) { return roleId == 1; } } /// /// 用户信息实体类 /// /// /// 包含用户的基本信息,如租户ID、角色ID、用户名等 /// public class UserInfo { /// /// 获取或设置租户ID /// public long TenantId { get; set; } /// /// 获取或设置用户角色ID /// public int RoleId { get; set; } /// /// 获取或设置用户的名称 /// public string UserName { get; set; } /// /// 获取或设置用户ID /// public int UserId { get; set; } /// /// 获取或设置用户的真实姓名 /// public string UserTrueName { get; set; } /// /// 获取或设置用户头像的URL /// public string HeadImageUrl { get; set; } } }