diff --git a/Yi.Framework.Net6/.dockerignore b/Yi.Framework.Net6/.dockerignore new file mode 100644 index 00000000..3729ff0c --- /dev/null +++ b/Yi.Framework.Net6/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs index 62ec149c..6d815d82 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs @@ -16,6 +16,7 @@ using Yi.Framework.DTOModel; using Yi.Framework.Interface; using Yi.Framework.Model.Models; using Yi.Framework.WebCore; +using Yi.Framework.WebCore.AuthorizationPolicy; using Yi.Framework.WebCore.Mapper; namespace Yi.Framework.ApiMicroservice.Controllers @@ -32,7 +33,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers private CacheClientDB _cacheClientDB; private IRoleService _roleService; private IHttpContextAccessor _httpContext; - public AccountController(ILogger logger, IUserService userService, IMenuService menuService,RabbitMQInvoker rabbitMQInvoker,CacheClientDB cacheClientDB, IRoleService roleService, IHttpContextAccessor httpContext) + public AccountController(ILogger logger, IUserService userService, IMenuService menuService, RabbitMQInvoker rabbitMQInvoker, CacheClientDB cacheClientDB, IRoleService roleService, IHttpContextAccessor httpContext) { _logger = logger; _userService = userService; @@ -52,18 +53,20 @@ namespace Yi.Framework.ApiMicroservice.Controllers [HttpPost] public async Task Login(loginDto login) { - var _user= MapperHelper.Map(login); + var _user = MapperHelper.Map(login); var user_data = await _userService.Login(_user); if (user_data == null) { return Result.Error("该用户不存在"); } var menuList = await _menuService.GetTopMenuByUserId(user_data.id); - if ( user_data!=null) - { - var token = MakeJwt.app(new jwtUser() {user=user_data,menuIds= menuList}); - + if (user_data != null) + { + var token = MakeJwt.app(new jwtUser() { user = user_data, menuIds = menuList }); JobModel.visitNum += 1; + //同时要将api路径放置到redis中 + var menuDto = MapperHelper.MapList(menuList); + _userService.SaveUserApi(user_data.id, menuDto); return Result.Success().SetData(new { user = new { user_data.id, user_data.username, user_data.introduction, user_data.icon, user_data.nick }, token }); } return Result.Error(); @@ -73,6 +76,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// 不用写,单纯制作日志 /// /// + [HttpPost] public Result Logout() { @@ -88,17 +92,17 @@ namespace Yi.Framework.ApiMicroservice.Controllers [HttpPost] public async Task Register(user _user, string code) { - _user.username=_user.username.Trim(); - if(string.IsNullOrEmpty(_user.username)) - code = code.Trim(); + _user.username = _user.username.Trim(); + if (string.IsNullOrEmpty(_user.username)) + code = code.Trim(); - string trueCode= _cacheClientDB.Get(RedisConst.keyCode + _user.phone); + string trueCode = _cacheClientDB.Get(RedisConst.keyCode + _user.phone); if (code == trueCode) { //设置默认头像 var setting = JsonHelper.StrToObj(_cacheClientDB.Get(RedisConst.key)); _user.icon = setting.InitIcon; - _user.ip = _httpContext.HttpContext.Request.Headers["X-Real-IP"].FirstOrDefault();//通过上下文获取ip + _user.ip = _httpContext.HttpContext?.Request.Headers["X-Real-IP"].FirstOrDefault();//通过上下文获取ip //设置默认角色 if (string.IsNullOrEmpty(setting.InitRole)) { @@ -120,7 +124,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// [HttpPost] - public async Task SendSMS(string SMSAddress) + public async Task SendSMS(string SMSAddress) { if (string.IsNullOrEmpty(SMSAddress)) { @@ -131,15 +135,15 @@ namespace Yi.Framework.ApiMicroservice.Controllers { SMSQueueModel sMSQueueModel = new SMSQueueModel(); sMSQueueModel.phone = SMSAddress; - sMSQueueModel.code =RandomHelper.GenerateCheckCodeNum(6); + sMSQueueModel.code = RandomHelper.GenerateCheckCodeNum(6); //10分钟过期 - _cacheClientDB.Set(RedisConst.keyCode+sMSQueueModel.phone, sMSQueueModel.code, TimeSpan.FromMinutes(10)); + _cacheClientDB.Set(RedisConst.keyCode + sMSQueueModel.phone, sMSQueueModel.code, TimeSpan.FromMinutes(10)); _rabbitMQInvoker.Send(new Common.IOCOptions.RabbitMQConsumerModel() { ExchangeName = RabbitConst.SMS_Exchange, QueueName = RabbitConst.SMS_Queue_Send }, JsonHelper.ObjToStr(sMSQueueModel)); return Result.Success("发送短信成功,10分钟后过期,请留意短信接收"); } - return Result.Error("该号码已被注册"); + return Result.Error("该号码已被注册"); } /// @@ -179,11 +183,11 @@ namespace Yi.Framework.ApiMicroservice.Controllers [HttpPut] [Authorize] public async Task ChangePassword(ChangePwdDto pwdDto) - { + { var user_data = await _userService.GetUserById(pwdDto.user.id); string msg = "修改成功"; - if (! string.IsNullOrEmpty( pwdDto.newPassword)) - { + if (!string.IsNullOrEmpty(pwdDto.newPassword)) + { if (user_data.password == pwdDto.user.password) { @@ -195,7 +199,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers user_data.address = pwdDto.user.address; user_data.nick = pwdDto.user.nick; - + await _userService.UpdateAsync(user_data); user_data.password = null; return Result.Success(msg); @@ -219,6 +223,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers return Result.Success(msg); } - + } } \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/MenuController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/MenuController.cs index ce14e68b..7bb08bd4 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/MenuController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/MenuController.cs @@ -19,9 +19,11 @@ namespace Yi.Framework.ApiMicroservice.Controllers public class MenuController : ControllerBase { private IMenuService _menuService; - public MenuController(IMenuService menuService) + private IUserService _userService; + public MenuController(IMenuService menuService,IUserService userService) { _menuService = menuService; + _userService = userService; } /// /// 这个是要递归的,但是要过滤掉删除的,所以,可以写一个通用过滤掉删除的方法 @@ -105,8 +107,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers [HttpGet] public async Task GetTopMenusByHttpUser() { - HttpContext.GetCurrentUserInfo(out List menuIds); - + var menuIds = _userService.GetCurrentMenuInfo(HttpContext.GetCurrentUserInfo().id); return Result.Success().SetData(await _menuService.GetTopMenusByTopMenuIds(menuIds)); } } diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/UserController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/UserController.cs index c552a081..bb580786 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/UserController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/UserController.cs @@ -10,6 +10,7 @@ using Yi.Framework.DTOModel; using Yi.Framework.Interface; using Yi.Framework.Model.Models; using Yi.Framework.WebCore; +using Yi.Framework.WebCore.AuthorizationPolicy; namespace Yi.Framework.ApiMicroservice.Controllers { @@ -31,6 +32,8 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// 查 /// /// + + [Authorize(PolicyName.Menu)] [HttpGet] public async Task GetUser() { @@ -43,6 +46,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// [HttpPut] + [Authorize(PolicyName.Menu)] public async Task UpdateUser(user _user) { await _userService.UpdateAsync(_user); @@ -56,6 +60,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// [HttpDelete] + [Authorize(PolicyName.Menu)] public async Task DelListUser(List _ids) { await _userService.DelListByUpdateAsync(_ids); @@ -68,6 +73,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers /// /// [HttpPost] + [Authorize(PolicyName.Menu)] public async Task AddUser(user _user) { await _userService.AddAsync(_user); @@ -109,7 +115,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers [HttpGet] public async Task GetMenuByHttpUser() { - HttpContext.GetCurrentUserInfo(out var allMenuIds); + var allMenuIds= _userService.GetCurrentMenuInfo(HttpContext.GetCurrentUserInfo().id); return Result.Success().SetData(await _userService.GetMenuByHttpUser(allMenuIds)); } @@ -121,8 +127,8 @@ namespace Yi.Framework.ApiMicroservice.Controllers [HttpGet] public async Task GetAxiosByRouter(string router) { - - var _user = HttpContext.GetCurrentUserInfo(out List menuIds); + var _user = HttpContext.GetCurrentUserInfo(); + var menuIds = _userService.GetCurrentMenuInfo(_user.id); if (menuIds == null) { return Result.Error(); diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs index 6a1ce8a9..3d8684a6 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Program.cs @@ -67,6 +67,10 @@ builder.Services.AddCorsService(); #endregion builder.Services.AddJwtService(); #region +//Ȩ +#endregion +builder.Services.AddAuthorizationService(); +#region //ݿ #endregion builder.Services.AddDbService(); diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj index d27a1c55..67e6d2f3 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj @@ -4,6 +4,8 @@ net6.0 enable enable + f5ce4739-9524-4330-9aea-cfcdb41501de + Linux @@ -23,6 +25,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/image/3e1a699a-6634-4378-a98d-76a082843c92.jpg b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/image/3e1a699a-6634-4378-a98d-76a082843c92.jpg new file mode 100644 index 00000000..aa4daf73 Binary files /dev/null and b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/wwwroot/image/3e1a699a-6634-4378-a98d-76a082843c92.jpg differ diff --git a/Yi.Framework.Net6/Yi.Framework.Common/Const/RedisConst.cs b/Yi.Framework.Net6/Yi.Framework.Common/Const/RedisConst.cs index 1c59a4db..13d1fa87 100644 --- a/Yi.Framework.Net6/Yi.Framework.Common/Const/RedisConst.cs +++ b/Yi.Framework.Net6/Yi.Framework.Common/Const/RedisConst.cs @@ -14,6 +14,8 @@ namespace Yi.Framework.Common.Const public const string key = "YiFramework:data"; public const string keyCode = "YiFramework:code"; + + public const string userMenusApi = "YiFramework:userMenusApi"; ///// ///// 初始化角色名 ///// diff --git a/Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs b/Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs index 32187406..c9ffbb7e 100644 --- a/Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs +++ b/Yi.Framework.Net6/Yi.Framework.Core/CacheClientDB.cs @@ -1040,9 +1040,14 @@ namespace Yi.Framework.Core public bool SetEntryInHash(string hashId, string key, T value) { + return this.TryCatch(() => this.client.SetEntryInHash(hashId, key, TextExtensions.SerializeToString(value)), hashId); } - + public bool SetEntryInHash(string hashId, string key, T value, TimeSpan expiresIn) + { + + return this.TryCatch(() => this.client.SetEntryInHash(hashId, key, TextExtensions.SerializeToString(value)), hashId); + } public T GetValueFromHash(string hashId, string key) { return this.TryCatch(() => JsonSerializer.DeserializeFromString(this.client.GetValueFromHash(hashId, key)), hashId); diff --git a/Yi.Framework.Net6/Yi.Framework.Core/MakeJwt.cs b/Yi.Framework.Net6/Yi.Framework.Core/MakeJwt.cs index 841351a2..08420c39 100644 --- a/Yi.Framework.Net6/Yi.Framework.Core/MakeJwt.cs +++ b/Yi.Framework.Net6/Yi.Framework.Core/MakeJwt.cs @@ -37,10 +37,11 @@ namespace Yi.Framework.Core claims.Add(new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}")); claims.Add(new Claim(ClaimTypes.Name, _user.user.username)); claims.Add(new Claim(ClaimTypes.Sid, _user.user.id.ToString())); - foreach (var k in _user?.menuIds) - { - claims.Add(new Claim("menuIds",k.id.ToString())); - } + //现在不存放在jwt中,而存放在redis中 + //foreach (var k in _user?.menuIds) + //{ + // claims.Add(new Claim("menuIds",k.id.ToString())); + //} foreach (var k in _user.user.roles) { claims.Add(new Claim(ClaimTypes.Role, k.role_name)); diff --git a/Yi.Framework.Net6/Yi.Framework.DTOModel/menuDto.cs b/Yi.Framework.Net6/Yi.Framework.DTOModel/menuDto.cs new file mode 100644 index 00000000..4e52123b --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.DTOModel/menuDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.Models; + +namespace Yi.Framework.DTOModel +{ + public class menuDto + { + public int id { get; set; } + public string icon { get; set; } + public string router { get; set; } + public string menu_name { get; set; } + + public mould mould { get; set; } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Interface/IUserService.cs b/Yi.Framework.Net6/Yi.Framework.Interface/IUserService.cs index 86f11bce..76a268d1 100644 --- a/Yi.Framework.Net6/Yi.Framework.Interface/IUserService.cs +++ b/Yi.Framework.Net6/Yi.Framework.Interface/IUserService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Yi.Framework.DTOModel; using Yi.Framework.Model.Models; namespace Yi.Framework.Interface @@ -67,5 +68,19 @@ namespace Yi.Framework.Interface /// Task> GetAxiosByRouter(string router,int userId, List menuIds); + + /// + /// 将登录用户的api保存的redis中 + /// + /// + /// + public bool SaveUserApi(int userId, List menus); + + /// + /// 通过用户id得到redis中菜单列表 + /// + /// + /// + public List GetCurrentMenuInfo(int userId); } } diff --git a/Yi.Framework.Net6/Yi.Framework.Interface/Yi.Framework.Interface.csproj b/Yi.Framework.Net6/Yi.Framework.Interface/Yi.Framework.Interface.csproj index cd69cc15..498021a8 100644 --- a/Yi.Framework.Net6/Yi.Framework.Interface/Yi.Framework.Interface.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Interface/Yi.Framework.Interface.csproj @@ -17,6 +17,7 @@ + diff --git a/Yi.Framework.Net6/Yi.Framework.Service/MenuService.cs b/Yi.Framework.Net6/Yi.Framework.Service/MenuService.cs index 41f71ca9..5eb878a7 100644 --- a/Yi.Framework.Net6/Yi.Framework.Service/MenuService.cs +++ b/Yi.Framework.Net6/Yi.Framework.Service/MenuService.cs @@ -66,7 +66,10 @@ namespace Yi.Framework.Service var m = u.menus.Where(u => u.is_delete == Normal).ToList(); menuList = menuList.Union(m).ToList(); }); - return menuList; + + var menuIds=menuList.Select(u => u.id).ToList(); + + return await _DbRead.Set().Include(u => u.mould).Where(u => menuIds.Contains(u.id)).ToListAsync(); } } diff --git a/Yi.Framework.Net6/Yi.Framework.Service/UserService.cs b/Yi.Framework.Net6/Yi.Framework.Service/UserService.cs index 6e9396cf..b679451d 100644 --- a/Yi.Framework.Net6/Yi.Framework.Service/UserService.cs +++ b/Yi.Framework.Net6/Yi.Framework.Service/UserService.cs @@ -5,7 +5,9 @@ using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; +using Yi.Framework.Common.Const; using Yi.Framework.Core; +using Yi.Framework.DTOModel; using Yi.Framework.Interface; using Yi.Framework.Model; using Yi.Framework.Model.ModelFactory; @@ -15,6 +17,11 @@ namespace Yi.Framework.Service { public partial class UserService : BaseService, IUserService { + CacheClientDB _cacheClientDB; + public UserService(CacheClientDB cacheClientDB, IDbContextFactory DbFactory) : base(DbFactory) + { + _cacheClientDB = cacheClientDB; + } short Normal = (short)Common.Enum.DelFlagEnum.Normal; public async Task PhoneIsExsit(string smsAddress) { @@ -42,42 +49,43 @@ namespace Yi.Framework.Service /// public async Task GetUserById(int userId) { - return await _DbRead.Set().Include(u => u.roles).ThenInclude(u => u.menus).ThenInclude(u => u.children).ThenInclude(u => u.mould).Where(u=>u.id==userId).FirstOrDefaultAsync(); + return await _DbRead.Set().Include(u => u.roles).ThenInclude(u => u.menus).ThenInclude(u => u.children).ThenInclude(u => u.mould).Where(u => u.id == userId).FirstOrDefaultAsync(); } - public async Task> GetAxiosByRouter(string router, int userId, List menuIds) + public async Task> GetAxiosByRouter(string router, int userId, List menuIds) { - var user_data =await GetUserById(userId); + var user_data = await GetUserById(userId); List menuList = new(); - foreach(var item in user_data.roles) + foreach (var item in user_data.roles) { - var m=item.menus.Where(u =>u?.router?.ToUpper() == router.ToUpper()).FirstOrDefault(); + var m = item.menus.Where(u => u?.router?.ToUpper() == router.ToUpper()).FirstOrDefault(); if (m == null) { break; } - menuList = m.children?.Where(u => menuIds.Contains(u.id)&&u.is_delete==Normal).ToList(); - + menuList = m.children?.Where(u => menuIds.Contains(u.id) && u.is_delete == Normal).ToList(); + } - return menuList; - } + return menuList; + } public async Task GetMenuByHttpUser(List allMenuIds) { - var topMenu =await _DbRead.Set().Include(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).Where(u => u.is_top == (short)Common.Enum.ShowFlagEnum.Show).FirstOrDefaultAsync(); + var topMenu = await _DbRead.Set().Include(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).Where(u => u.is_top == (short)Common.Enum.ShowFlagEnum.Show).FirstOrDefaultAsync(); //现在要开始关联菜单了 return TreeMenuBuild.Sort(TreeMenuBuild.ShowFormat(topMenu, allMenuIds)); ; - } + } public async Task GetUserInRolesByHttpUser(int userId) { var data = await GetUserById(userId); - data.roles?.ForEach(u=> { + data.roles?.ForEach(u => + { u.users = null; u.menus = null; }); - return data; + return data; } public async Task Login(user _user) { - var user_data = await _DbRead.Set().Include(u => u.roles).Where(u => u.username == _user.username && u.password ==_user.password &&u.is_delete == Normal).FirstOrDefaultAsync(); + var user_data = await _DbRead.Set().Include(u => u.roles).Where(u => u.username == _user.username && u.password == _user.password && u.is_delete == Normal).FirstOrDefaultAsync(); return user_data; } @@ -93,12 +101,19 @@ namespace Yi.Framework.Service public async Task SetRoleByUser(List roleIds, List userIds) { - var user_data = await _DbRead.Set().Include(u => u.roles).Where(u => userIds.Contains(u.id)).ToListAsync(); + var user_data = await _DbRead.Set().Include(u => u.roles).Where(u => userIds.Contains(u.id)).ToListAsync(); var roleList = await _DbRead.Set().Where(u => roleIds.Contains(u.id)).ToListAsync(); - user_data.ForEach(u => u.roles = roleList); + user_data.ForEach(u => u.roles = roleList); return await UpdateListAsync(user_data); } - + public bool SaveUserApi(int userId, List menus) + { + return _cacheClientDB.Set(RedisConst.userMenusApi+":"+userId.ToString(),menus,new TimeSpan(0,30,0)); + } + public List GetCurrentMenuInfo(int userId) + { + return _cacheClientDB.Get>(RedisConst.userMenusApi+":"+userId).Select(u=>u.id).ToList(); + } } } diff --git a/Yi.Framework.Net6/Yi.Framework.Service/Yi.Framework.Service.csproj b/Yi.Framework.Net6/Yi.Framework.Service/Yi.Framework.Service.csproj index 7d3c9014..3591bcb8 100644 --- a/Yi.Framework.Net6/Yi.Framework.Service/Yi.Framework.Service.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Service/Yi.Framework.Service.csproj @@ -18,6 +18,7 @@ + diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/CustomAuthorizationHandler.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/CustomAuthorizationHandler.cs new file mode 100644 index 00000000..111842ea --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/CustomAuthorizationHandler.cs @@ -0,0 +1,89 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Yi.Framework.Common.Const; +using Yi.Framework.Core; +using Yi.Framework.DTOModel; +using Yi.Framework.Model.Models; + +namespace Yi.Framework.WebCore.AuthorizationPolicy +{ + //策略验证的Handler 继承AuthorizationHandler 泛型类 泛型参数为 策略参数 + public class CustomAuthorizationHandler : AuthorizationHandler + { + + private CacheClientDB _cacheClientDB; + /// + /// 构造函数 + /// + public CustomAuthorizationHandler(CacheClientDB cacheClientDB) + { + _cacheClientDB= cacheClientDB; + } + + //验证的方法就在这里 + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) + { + var currentClaim = context.User.Claims.FirstOrDefault(u => u.Type == ClaimTypes.Sid); + + if (currentClaim==null) //说明没有写入Sid 没有登录 + { + return Task.CompletedTask; //验证不同过 + } + + int currentUserId = 0; + if (!string.IsNullOrWhiteSpace(currentClaim.Value)) + { + currentUserId = Convert.ToInt32(currentClaim.Value); + } + DefaultHttpContext httpcontext = (DefaultHttpContext)context.Resource; + Dictionary dicMenueDictionary = new Dictionary(); + //现在只需要登录的时候把用户的api路径添加到redis去 + //每次访问的时候进行redis判断一下即可 + //注意一下,redis不能一直保存,和jwt一样搞一个期限 + var menuList=_cacheClientDB.Get>(RedisConst.userMenusApi+":"+currentUserId); + foreach (var k in menuList) + { + if (k.mould != null) + { + dicMenueDictionary.Add(k.mould?.id.ToString(), "/api"+ k.mould?.url); + } + + } + + if (dicMenueDictionary.ContainsValue(httpcontext.Request.Path)) + { + context.Succeed(requirement); //验证通过了 + } + return Task.CompletedTask; //验证不同过 + + } + } + + + /// + /// 菜单权限策略 + /// + public static class CustomAuthorizationHandlerExtension + { + public static Task AuthorizationMenueExtension(this AuthorizationHandlerContext handlerContext, CustomAuthorizationRequirement requirement) + { + bool bog = true; + if (bog) + { + return Task.Run(() => + { + handlerContext.Succeed(requirement); //验证通过了 + }); + } + else + { + return Task.CompletedTask; //验证不同过 + } + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/CustomAuthorizationRequirement.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/CustomAuthorizationRequirement.cs new file mode 100644 index 00000000..a2b72310 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/CustomAuthorizationRequirement.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Authorization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Yi.Framework.WebCore.AuthorizationPolicy +{ + //定义策略参数,必须实现这个IAuthorizationRequirement接口 + public class CustomAuthorizationRequirement: IAuthorizationRequirement + { + public CustomAuthorizationRequirement(PolicyEnum policyname) + { + this.PolicyName = policyname; + } + public PolicyEnum PolicyName { get; set; } + + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/PolicyEnum.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/PolicyEnum.cs new file mode 100644 index 00000000..ad8ac425 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/AuthorizationPolicy/PolicyEnum.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Yi.Framework.WebCore.AuthorizationPolicy +{ + public enum PolicyEnum + { + /// + /// 菜单 + /// + MenuPermissions, + //...还可以定义其他的各种权限策略名称 + } + public static class PolicyName + { + public const string Menu = "Menu"; + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs index 35bf7cda..ccdc66ac 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/CommonExtend.cs @@ -26,6 +26,7 @@ namespace Yi.Framework.WebCore /// /// 基于HttpContext,当前鉴权方式解析,获取用户信息 + /// 现在使用redis作为缓存,不需要将菜单存放至jwt中了 /// /// /// diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/Mapper/MapperHelper.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/Mapper/MapperHelper.cs index d8b1b5f9..2812369f 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/Mapper/MapperHelper.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/Mapper/MapperHelper.cs @@ -28,5 +28,13 @@ namespace Yi.Framework.WebCore.Mapper IMapper mapper = new AutoMapper.Mapper(config); return mapper.Map(source); } + public static List MapList(List source) + { + var cfg = new MapperConfigurationExpression(); + cfg.CreateMap(); + var config = new MapperConfiguration(cfg); + IMapper mapper = new AutoMapper.Mapper(config); + return mapper.Map, List>(source); + } } } diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/AuthorizationExtension.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/AuthorizationExtension.cs new file mode 100644 index 00000000..826520b9 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/AuthorizationExtension.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.WebCore.AuthorizationPolicy; + +namespace Yi.Framework.WebCore.MiddlewareExtend +{ + public static class AuthorizationExtension + { + public static IServiceCollection AddAuthorizationService(this IServiceCollection services) + { + services.AddAuthorization(options => + { + options.AddPolicy(PolicyName.Menu, polic => + { + polic.AddRequirements(new CustomAuthorizationRequirement(PolicyEnum.MenuPermissions)); + }); + }); + + services.AddSingleton(); + return services; + } + } +}