• .NET 云原生架构师训练营(权限系统 代码实现 Store.EntityFramework)--学习笔记


    目录

    • 开发任务
    • 代码实现

    开发任务

    • DotNetNB.Security.Core:定义 core,models,Istore;实现 default memory store
    • DotNetNB.Security.Store.EntityFramework:基于 mysql 创建 PermissionStore 和 ResourceStore

    代码实现

    我们需要在 ResourceProviderHostedService 中读取所有的 Resource,将 Resource 转换为 Permission,再将 Permission 分配给 Role

    创建 Permission 的 model

    namespace DotNetNB.Security.Core.Models
    {
        public class Permission
        {
            public string Key { get; set; }
    
            public string DisplayName { get; set; }
    
            public string Description { get; set; }
    
            public IEnumerable Resources { get; set; }
        }
    }
    

    在 IPermissionManager 接口中定义 CreateAsync 方法

    namespace DotNetNB.Security.Core
    {
        public interface IPermissionManager
        {
            public Task CreateAsync(string key, string displayName, string description, IEnumerable<string> resources);
        }
    }
    

    IResourceManager 接口添加通过 key 获取 resource 的方法 GetByKeysAsync

    public Task<IEnumerable<Resource>> GetByKeysAsync(IEnumerable resources);
    

    PermissionManager 里面需要用到 Store,先定义接口 IPermissionStore

    using DotNetNB.Security.Core.Models;
    
    namespace DotNetNB.Security.Core.Store
    {
        public interface IPermissionStore
        {
            public Task CreateAsync(Permission permission);
        }
    }
    

    在 PermissionManager 里面创建一个 permission,通过 ResourceManager 获取到所有 resources 赋值给 permission,再将 permission 存储到 PermissionStore

    using DotNetNB.Security.Core.Models;
    using DotNetNB.Security.Core.Store;
    
    namespace DotNetNB.Security.Core;
    
    public class PermissionManager: IPermissionManager
    {
        private readonly IResourceManager _resourceManager;
        private readonly IPermissionStore _permissionStore;
    
        public PermissionManager(IResourceManager resourceManager, IPermissionStore permissionStore)
        {
            _resourceManager = resourceManager;
            _permissionStore = permissionStore;
        }
    
        public async Task CreateAsync(string key, string displayName, string description, IEnumerable<string> resourceKeys)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException(nameof(key));
    
            var permission = new Permission { Key = key, DisplayName = displayName, Description = description };
            var resources = await _resourceManager.GetByKeysAsync(resourceKeys);
            permission.Resources = resources;
    
            await _permissionStore.CreateAsync(permission);
        }
    }
    

    创建 DefaultPermissionStore 实现 IPermissionStore

    using DotNetNB.Security.Core.Models;
    
    namespace DotNetNB.Security.Core.Store
    {
        public class DefaultPermissionStore : IPermissionStore
        {
            private List _list;
    
            public DefaultPermissionStore()
            {
                _list = new List();
            }
    
            public async Task CreateAsync(Permission permission)
            {
                _list.Add(permission);
            }
        }
    }
    

    IPermissionStore 接口添加获取 permission 列表的方法

    public Task<IEnumerable<Permission>> GetAllAsync();
    

    在 DefaultPermissionStore 中直接将列表返回即可

    public async Task<IEnumerable<Permission>> GetAllAsync()
    {
        return _list;
    }
    

    在 PermissionManager 中通过 PermissionStore 获取 Permission 列表返回

    public async Task<IEnumerable<Permission>> GetAllAsync()
    {
        return await _permissionStore.GetAllAsync();
    }
    

    在 IPermissionStore 中添加 GetByKeyAsync 方法,在 PermissionManager 中用于校验 key 是否存在对应的 Permission

    public Task GetByKeyAsync(string key);
    

    在 DefaultPermissionStore 中实现 GetByKeyAsync 方法

    public async Task GetByKeyAsync(string key)
    {
        return _list.SingleOrDefault(r => r.Key == key);
    }
    

    在 PermissionManager 中校验 key 是否存在对应的 Permission

    var origin = await _permissionStore.GetByKeyAsync(key);
    if (origin != null)
        throw new InvalidOperationException("Duplicated permission key found");
    

    IResourceManager 接口添加获取所有 resource 方法 GetAllAsync

    public Task<IEnumerable<Resource>> GetAllAsync();
    

    ResourceManager 里面需要用到 Store,先定义接口 IResourceStore

    using DotNetNB.Security.Core.Models;
    
    namespace DotNetNB.Security.Core.Store
    {
        public interface IResourceStore
        {
            public Task CreateAsync(Resource resource);
    
            public Task CreateAsync(IEnumerable resources);
    
            public Task> GetAllAsync();
            
            public Task GetByKeyAsync(string key);
    
            public Task> GetByKeysAsync(IEnumerable<string> resources);
        }
    }
    

    创建 DefaultResourceStore 实现 IResourceStore

    using DotNetNB.Security.Core.Models;
    
    namespace DotNetNB.Security.Core.Store
    {
        public class DefaultResourceStore : IResourceStore
        {
            private readonly List _list;
    
            public DefaultResourceStore()
            {
                _list = new List();
            }
    
            public async Task CreateAsync(Resource resource)
            {
                _list.Add(resource);
            }
    
            public async Task CreateAsync(IEnumerable resources)
            {
                _list.AddRange(resources);
            }
    
            public async Task> GetAllAsync()
            {
                return _list;
            }
    
            public async Task GetByKeyAsync(string key)
            {
                return _list.SingleOrDefault(r => r.Key == key);
            }
    
            public async Task> GetByKeysAsync(IEnumerable<string> resources)
            {
                return _list.Where(r => resources.Contains(r.Key));
            }
        }
    }
    

    在 ResourceManager 中通过 ResourceStore 创建存储获取 Resource,创建的时候判断是否已经存在 Resource

    using DotNetNB.Security.Core.Models;
    using DotNetNB.Security.Core.Store;
    
    namespace DotNetNB.Security.Core
    {
        public class ResourceManager :  IResourceManager
        {
            private readonly IResourceStore _resourceStore;
            public ResourceManager(IResourceStore resourceStore)
            {
                _resourceStore = resourceStore;
            }
    
            public async Task CreateAsync(Resource resource)
            {
                var origin = await _resourceStore.GetByKeyAsync(resource.Key);
                if (origin != null)
                    throw new InvalidOperationException("Duplicated resource key found");
    
                await _resourceStore.CreateAsync(resource);
            }
    
            public async Task CreateAsync(IEnumerable resources)
            {
                var origins = await _resourceStore.GetByKeysAsync(resources.Select(r => r.Key));
                if (origins.Any())
                    throw new InvalidOperationException($"Duplicated resource key found:{string.Concat(origins.Select(o => o.Key), ",")}");
    
                await _resourceStore.CreateAsync(resources);
            }
    
            public async Task> GetAllAsync()
            {
                return await _resourceStore.GetAllAsync();
            }
    
            public async Task> GetByKeysAsync(IEnumerable<string> resources)
            {
                return await _resourceStore.GetByKeysAsync(resources);
            }
        }
    }
    

    GitHub源码链接:

    https://github.com/MingsonZheng/dotnetnb.security

    课程链接

    https://appsqsyiqlk5791.h5.xiaoeknow.com/v1/course/video/v_5f39bdb8e4b01187873136cf?type=2

    知识共享许可协议

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

    欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

    如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

  • 相关阅读:
    群晖系统安装相关文件分享
    「网工必备」五款工作学习必备软件免费下载
    【模型篇】01 记点脑子里还残存的关于模型分类的三种方式
    一、HTML&CSS
    计算机毕业设计springboot+vue基本微信小程序的汽车租赁公司小程序
    [Android]从app的trace打桩原理回顾zygote的fork
    RK3568 SPI子系统–oled屏
    【mysql】mysql数据库出现Communications link failure
    Python零基础入门-9类
    【二叉树】——链式结构(快速掌握递归与刷题技巧)
  • 原文地址:https://www.cnblogs.com/MingsonZheng/p/15906650.html