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; }
}
}