You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DSWMS/Vue.Net/VOL.Core/UserManager/UserContext.cs

411 lines
15 KiB
C#

2 years ago
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using VOL.Core.CacheManager;
using VOL.Core.DBManager;
using VOL.Core.Enums;
using VOL.Core.Extensions;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity;
using VOL.Entity.DomainModels;
using ConvertHelper;
namespace VOL.Core.ManageUser
{
public class UserContext
{
/// <summary>
/// 为了尽量减少redis或Memory读取,保证执行效率,将UserContext注入到DI
/// 每个UserContext的属性至多读取一次redis或Memory缓存从而提高查询效率
/// </summary>
public static UserContext Current
{
get
{
return Context.RequestServices.GetService(typeof(UserContext)) as UserContext;
}
}
private static Microsoft.AspNetCore.Http.HttpContext Context
{
get
{
return Utilities.HttpContext.Current;
}
}
private static ICacheService CacheService
{
get { return GetService<ICacheService>(); }
}
private static T GetService<T>() where T : class
{
return AutofacContainerModule.GetService<T>();
}
public UserInfo UserInfo
{
get
{
if (_userInfo != null)
{
return _userInfo;
}
return GetUserInfo(UserId);
}
}
private UserInfo _userInfo { get; set; }
private const string AdministratorId= "1BEC90E1-9780-472F-90C2-0C6390C044A4";
/// <summary>
/// 角色ID为1的默认为超级管理员
/// </summary>
public bool IsSuperAdmin
{
get { return IsRoleIdSuperAdmin(this.RoleId); }
}
/// <summary>
/// 角色ID为1的默认为超级管理员
/// </summary>
public static bool IsRoleIdSuperAdmin(string roleId)
{
return roleId == "1";
}
public UserInfo GetUserInfo(Guid userId)
{
if (_userInfo != null) return _userInfo;
if (userId.isNullorEmpty())
{
_userInfo = new UserInfo();
return _userInfo;
}
string key = userId.GetUserIdKey();
_userInfo = CacheService.Get<UserInfo>(key);
if (_userInfo != null && !_userInfo.User_Id.isNullorEmpty() ) return _userInfo;
_userInfo = DBServerProvider.DbContext.Set<Sys_User>()
.Where(x => (x.User_Id== userId)).Select(s => new UserInfo()
{
User_Id = userId,
Role_Id = s.Role_Id,//.GetInt()
RoleName = s.RoleName,
Token = s.Token,
UserName = s.UserName,
UserTrueName = s.UserTrueName,
Enable = s.Enable,
CompanyId=s.CompanyId,
Dept_Id=s.Dept_Id,
CompanyName=s.CompanyName
}).FirstOrDefault();
var currrole = DBServerProvider.DbContext.Set<Sys_Role>().First(x => x.Role_Id == _userInfo.Role_Id);
_userInfo.LimitInCompany = currrole.LimitCompanyRange==null?true:(bool)currrole.LimitCompanyRange;
_userInfo.LimitBySTORAGE = currrole.LimitBySTORAGE == null ? true : (bool)currrole.LimitBySTORAGE;
//如果 _userInfo.LimitBySTORAGE == true
//从VW_OP_WMS_STOREHOUSE_USERLIMIT中查出这个用户userid的所有记录
//据此查出所有他可以看的仓库id 然后转换为四位编码
if (_userInfo.LimitBySTORAGE) {
var userStorehouseLimitList = DBServerProvider.DbContext.Set<OP_WMS_STOREHOUSE_USERLIMIT>().Where(x => x.USERID == _userInfo.User_Id).Select(s=>s.Pid).ToList();
var storehouseList = DBServerProvider.DbContext.Set<OP_WMS_STOREHOUSE>().Where(x => userStorehouseLimitList.Contains( x.Id )).ToList();
_userInfo.STOREHOUSEList = new List<string>();
foreach (var item in storehouseList) {
_userInfo.STOREHOUSEList.Add(item.AREACODE);
}
}
if (_userInfo != null && !_userInfo.User_Id.isNullorEmpty())
{
CacheService.AddObject(key, _userInfo);
}
return _userInfo ?? new UserInfo();
}
/// <summary>
/// 获取角色权限时通过安全字典锁定的角色id
/// </summary>
private static ConcurrentDictionary<string, object> objKeyValue = new ConcurrentDictionary<string, object>();
/// <summary>
/// 角色权限的版本号
/// </summary>
private static readonly Dictionary<string, string> rolePermissionsVersion = new Dictionary<string, string>();
/// <summary>
/// 每个角色ID对应的菜单权限已做静态化处理
/// 每次获取权限时用当前服务器的版本号与redis/memory缓存的版本比较,如果不同会重新刷新缓存
/// </summary>
private static readonly Dictionary<string, List<Permissions>> rolePermissions = new Dictionary<string, List<Permissions>>();
/// <summary>
/// 获取用户所有的菜单权限
/// </summary>
public List<Permissions> Permissions
{
get
{
return GetPermissionsByRoleId(RoleId);
}
}
/// <summary>
/// 获取单个表的权限
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
public Permissions GetPermissions(string tableName)
{
return GetPermissionsByRoleId(RoleId).Where(x => x.TableName == tableName).FirstOrDefault();
}
/// <summary>
/// 自定条件查询权限
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
public Permissions GetPermissions(Func<Permissions, bool> func)
{
return GetPermissionsByRoleId(RoleId).Where(func).FirstOrDefault();
}
private List<Permissions> ActionToArray(List<Permissions> permissions)
{
permissions.ForEach(x =>
{
try
{
x.UserAuthArr = string.IsNullOrEmpty(x.UserAuth)
? new string[0]
: x.UserAuth.Split(",");
}
catch { }
finally
{
if (x.UserAuthArr == null)
{
x.UserAuthArr = new string[0];
}
}
});
return permissions;
}
private List<Permissions> MenuActionToArray(List<Permissions> permissions)
{
permissions.ForEach(x =>
{
try
{
x.UserAuthArr = string.IsNullOrEmpty(x.UserAuth)
? new string[0]
: x.UserAuth.DeserializeObject<List<Sys_Actions>>().Select(s => s.Value).ToArray();
}
catch { }
finally
{
if (x.UserAuthArr == null)
{
x.UserAuthArr = new string[0];
}
}
});
return permissions;
}
public List<Permissions> GetPermissionsByRoleId(string roleId)
{
if (IsRoleIdSuperAdmin(roleId))
{
var permissions_I = DBServerProvider.DbContext.Set<Sys_Menu>().Where(x => x.Enable == 1).Select(a => new Permissions
{
Menu_Id = a.Menu_Id,
ParentId = a.ParentId,
//2020.05.06增加默认将表名转换成小写,权限验证时不再转换
TableName = (a.TableName ?? "").ToLower(),
//MenuAuth = a.Auth,
UserAuth = a.Auth,
});
var permissions= permissions_I.ToList();
//var menutablename = new List<string>();
//foreach (var item in permissions) {
// menutablename.Add(item.TableName);
//}
//var alltable = DBServerProvider.DbContext.Set<Sys_TableInfo>().Where(x => !menutablename.Contains(x.TableName)).ToList();
//foreach (var item in alltable) {
// permissions.Add(new Permissions { Menu_Id = 9999, ParentId=9999,TableName= item.TableName.ToLower(), })
//}
return MenuActionToArray(permissions);
}
ICacheService cacheService = CacheService;
string roleKey = roleId.GetRoleIdKey();
//角色有缓存并且当前服务器的角色版本号与redis/memory缓存角色的版本号相同直接返回静态对象角色权限
string currnetVeriosn = "";
if (rolePermissionsVersion.TryGetValue(roleId, out currnetVeriosn)
&& currnetVeriosn == cacheService.Get(roleKey))
{
return rolePermissions.ContainsKey(roleId) ? rolePermissions[roleId] : new List<Permissions>();
}
//锁定每个角色,通过安全字典减少锁粒度,否则多个同时角色获取缓存会导致阻塞
object objId = objKeyValue.GetOrAdd(roleId.ToString(), new object());
//锁定每个角色
lock (objId)
{
if (rolePermissionsVersion.TryGetValue(roleId, out currnetVeriosn)
&& currnetVeriosn == cacheService.Get(roleKey))
{
return rolePermissions.ContainsKey(roleId) ? rolePermissions[roleId] : new List<Permissions>();
}
//没有redis/memory缓存角色的版本号或与当前服务器的角色版本号不同时刷新缓存
var dbContext = DBServerProvider.DbContext;
List<Permissions> _permissions = (from a in dbContext.Set<Sys_Menu>()
join b in dbContext.Set<Sys_RoleAuth>()
on a.Menu_Id equals b.Menu_Id
where b.Role_Id == roleId //&& a.ParentId > 0
&& b.AuthValue != ""
orderby a.ParentId
select new Permissions
{
Menu_Id = a.Menu_Id,
ParentId = a.ParentId,
//2020.05.06增加默认将表名转换成小写,权限验证时不再转换
TableName = (a.TableName ?? "").ToLower(),
MenuAuth = a.Auth,
UserAuth = b.AuthValue ?? ""
}).ToList();
var menutablename = new List<string>();
foreach (var item in _permissions)
{
menutablename.Add(item.TableName);
}
var alltable = DBServerProvider.DbContext.Set<Sys_TableInfo>().Where(x => !menutablename.Contains(x.TableName)).ToList();
foreach (var item in alltable)
{
_permissions.Add(new Permissions { Menu_Id = 9999, ParentId = 9999, TableName = item.TableName.ToLower(),UserAuth= "Search,Add,Delete,Update,Import,Export,Upload,Audit" });
}
ActionToArray(_permissions);
string _version = cacheService.Get(roleKey);
//生成一个唯一版本号标识
if (_version == null)
{
_version = DateTime.Now.ToString("yyyyMMddHHMMssfff");
//将版本号写入缓存
cacheService.Add(roleKey, _version);
}
//刷新当前服务器角色的权限
rolePermissions[roleId] = _permissions;
//写入当前服务器的角色最新版本号
rolePermissionsVersion[roleId] = _version;
return _permissions;
}
}
/// <summary>
/// 判断是否有权限
/// </summary>
/// <param name="tableName"></param>
/// <param name="authName"></param>
/// <param name="roleId"></param>
/// <returns></returns>
public bool ExistsPermissions(string tableName, string authName, string roleId = "")
{
if (string.IsNullOrWhiteSpace( roleId)) roleId = RoleId;
tableName = tableName.ToLower();
authName = authName.ToLower();
return GetPermissionsByRoleId(roleId).Any(x => x.TableName == tableName && x.UserAuthArr.Contains(authName));
}
/// <summary>
/// 判断是否有权限
/// </summary>
/// <param name="tableName"></param>
/// <param name="authName"></param>
/// <param name="roleId"></param>
/// <returns></returns>
public bool ExistsPermissions(string tableName, ActionPermissionOptions actionPermission, string roleId ="")
{
return ExistsPermissions(tableName, actionPermission.ToString(),roleId);
}
public Guid UserId
{
get
{
Guid result = Guid.Empty;
try
{
//var _r=(Context.User.FindFirstValue(JwtRegisteredClaimNames.Jti)
//?? Context.User.FindFirstValue(ClaimTypes.NameIdentifier)).GetInt();
var r1 = Context.User.FindFirstValue(JwtRegisteredClaimNames.Jti);
var r2 = Context.User.FindFirstValue(ClaimTypes.NameIdentifier);
if (r1 == null && r2 == null) result = Guid.Empty;
else
{
var _r = (r1 ?? r2).ToString();
result = new Guid(_r);
}
//result = (Context.User.FindFirstValue(JwtRegisteredClaimNames.Jti)
//?? Context.User.FindFirstValue(ClaimTypes.NameIdentifier)).ToString();
return result;
}
catch (Exception e) {
return result;
}
}
}
public string UserName
{
get { return UserInfo.UserName; }
}
public string UserTrueName
{
get { return UserInfo.UserTrueName; }
}
public string Token
{
get { return UserInfo.Token; }
}
public string RoleId
{
get { return UserInfo.Role_Id; }
}
public void LogOut(Guid userId)
{
CacheService.Remove(userId.GetUserIdKey());
}
}
}