目录

  • 开发任务
  • 代码实现

开发任务

  • 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<Resource> 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<string> 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<Permission> _list; public DefaultPermissionStore()
{
_list = new List<Permission>();
} 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<Permission> GetByKeyAsync(string key);

在 DefaultPermissionStore 中实现 GetByKeyAsync 方法

public async Task<Permission> 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<Resource> resources); public Task<IEnumerable<Resource>> GetAllAsync(); public Task<Resource> GetByKeyAsync(string key); public Task<IEnumerable<Resource>> GetByKeysAsync(IEnumerable<string> resources);
}
}

创建 DefaultResourceStore 实现 IResourceStore

using DotNetNB.Security.Core.Models;

namespace DotNetNB.Security.Core.Store
{
public class DefaultResourceStore : IResourceStore
{
private readonly List<Resource> _list; public DefaultResourceStore()
{
_list = new List<Resource>();
} public async Task CreateAsync(Resource resource)
{
_list.Add(resource);
} public async Task CreateAsync(IEnumerable<Resource> resources)
{
_list.AddRange(resources);
} public async Task<IEnumerable<Resource>> GetAllAsync()
{
return _list;
} public async Task<Resource> GetByKeyAsync(string key)
{
return _list.SingleOrDefault(r => r.Key == key);
} public async Task<IEnumerable<Resource>> 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<Resource> 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<IEnumerable<Resource>> GetAllAsync()
{
return await _resourceStore.GetAllAsync();
} public async Task<IEnumerable<Resource>> 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) 。

.NET 云原生架构师训练营(权限系统 代码实现 Store.EntityFramework)--学习笔记的更多相关文章

  1. .NET 云原生架构师训练营(设计原则与模式)--学习笔记

    在复杂系统的架构设计中引入设计原则与模式,能够极大降低复杂系统开发.和维护的成本 目录 几个问题 为什么要学习设计模式 优良架构设计的具体指标 理解复杂系统 面向对象思想(指导复杂系统的分析.设计.实 ...

  2. .NET 云原生架构师训练营(KestrelServer源码分析)--学习笔记

    目录 目标 源码 目标 理解 KestrelServer 如何接收网络请求,网络请求如何转换成 http request context(C# 可识别) 源码 https://github.com/d ...

  3. .NET 云原生架构师训练营(系统架构)--学习笔记

    目录 对外展现的功能 内部功能 功能交互与价值通路 系统架构 目标 认识系统的价值通路 认识功能架构,通过把功能结构与形式结构结合来描述系统架构 受益原则 好的架构必须使人受益,要想把架构做好,就要专 ...

  4. .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记

    目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ...

  5. .NET 云原生架构师训练营(权限系统 RGCA 架构设计)--学习笔记

    目录 项目核心内容 实战目标 RGCA 四步架构法 项目核心内容 无代码埋点实现对所有 API Action 访问控制管理 对 EF Core 实体新增.删除.字段级读写控制管理 与 Identity ...

  6. .NET 云原生架构师训练营(权限系统 RGCA 开发任务)--学习笔记

    目录 目标 模块拆分 OPM 开发任务 目标 基于上一讲的模块划分做一个任务拆解,根据任务拆解实现功能 模块拆分 模块划分已经完成了边界的划分,边界内外职责清晰 OPM 根据模块拆分画出 OPM(Ob ...

  7. .NET 云原生架构师训练营(建立系统观)--学习笔记

    目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ...

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

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...

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

    目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...

  10. .NET 云原生架构师训练营(权限系统 代码重构)--学习笔记

    目录 模块拆分 代码重构 模块拆分 代码重构 AuthenticationController PermissionController IAuthorizationMiddlewareResultH ...

随机推荐

  1. VMware 创建的虚拟机,Xshell无法进行连接

    使用场景: 在VMware 创建了Centos7后,Xshell一直连接不上,如果排查以下问题还是不行.就可以用这种方法了 1.配置了静态地址 2.VMware配置了NAT映射,划分了网段后 3.检查 ...

  2. Git 基础指令

    Git 基础指令 Git 基础指令 获取 Git 仓库 在已存在目录中初始化仓库 克隆现有的仓库 记录仓库与仓库的更新 仓库的记录 检查当前文件状态 三部曲 跟踪新文件 提交更新 移除文件 推送到远程 ...

  3. js数组清空的两种方式

    编辑器加载中...方式1,length赋值为0 这种方式很有意思, 其它语言如Java,其数组的length是只读的,不能被赋值.如 int[] ary = {1,2,3,4}; ary.length ...

  4. Vulnhub - THE PLANETS: EARTH

    环境配置 从www.vulnhub.com下载靶机,在VMware中导入,自动分配IP 主机发现 通过对内网主机的扫描,VMware为目标主机 端口扫描 使用nmap对主机进行扫描 发现443端口信息 ...

  5. Cesium入门9 - Loading and Styling Entities - 加载和样式化实体

    Cesium入门9 - Loading and Styling Entities - 加载和样式化实体 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://c ...

  6. 云图说|DDS读写两步走,带您领略只读节点的风采

    摘要:为了扩展主节点的读请求能力,DDS提供具备独立连接地址的只读节点,适合独立系统直连访问,以缓解大量读请求给主节点造成的压力. 本文分享自华为云社区<[云图说]第235期 DDS读写两步走 ...

  7. 领域驱动设计-CQRS

    CQRS 代表命令查询职责分离.这是我第一次听到Greg Young描述的模式.其核心概念是,您可以使用与用于读取信息的模型不同的模型来更新信息.在某些情况下,这种分离可能很有价值,但请注意,对于大多 ...

  8. React/Vue 项目在 GitHub Pages 上部署时资源的路径问题

    GitHub Pages 常被用来部署个人博客,而无论是大名鼎鼎的 Jekyll,还是 Hugo 或者 Hexo,他们都是将我们的文章嵌入模板,发布为静态页面,也就是说,GitHub Pages (G ...

  9. strace -cp 诊断

    strace -c php do.php 各项含义如下: - % time:执行耗时占总时间百分比 - seconds:执行总时间 - usecs/call:单个命令执行时间 - calls:调用次数 ...

  10. maven常用打包命令

    常用maven命令 执行与构建过程(编译,测试,打包)相关的命令必须进入pom.xml所在位置执行 mvn clean:清理(打包好的程序放在生成的名为target的文件中,清理即删除文件中打包好的程 ...