.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<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)--学习笔记的更多相关文章
- .NET 云原生架构师训练营(设计原则与模式)--学习笔记
在复杂系统的架构设计中引入设计原则与模式,能够极大降低复杂系统开发.和维护的成本 目录 几个问题 为什么要学习设计模式 优良架构设计的具体指标 理解复杂系统 面向对象思想(指导复杂系统的分析.设计.实 ...
- .NET 云原生架构师训练营(KestrelServer源码分析)--学习笔记
目录 目标 源码 目标 理解 KestrelServer 如何接收网络请求,网络请求如何转换成 http request context(C# 可识别) 源码 https://github.com/d ...
- .NET 云原生架构师训练营(系统架构)--学习笔记
目录 对外展现的功能 内部功能 功能交互与价值通路 系统架构 目标 认识系统的价值通路 认识功能架构,通过把功能结构与形式结构结合来描述系统架构 受益原则 好的架构必须使人受益,要想把架构做好,就要专 ...
- .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ...
- .NET 云原生架构师训练营(权限系统 RGCA 架构设计)--学习笔记
目录 项目核心内容 实战目标 RGCA 四步架构法 项目核心内容 无代码埋点实现对所有 API Action 访问控制管理 对 EF Core 实体新增.删除.字段级读写控制管理 与 Identity ...
- .NET 云原生架构师训练营(权限系统 RGCA 开发任务)--学习笔记
目录 目标 模块拆分 OPM 开发任务 目标 基于上一讲的模块划分做一个任务拆解,根据任务拆解实现功能 模块拆分 模块划分已经完成了边界的划分,边界内外职责清晰 OPM 根据模块拆分画出 OPM(Ob ...
- .NET 云原生架构师训练营(建立系统观)--学习笔记
目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ...
- .NET 云原生架构师训练营(权限系统 代码实现 ActionAccess)--学习笔记
目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...
- .NET 云原生架构师训练营(权限系统 代码实现 Identity)--学习笔记
目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.Secu ...
- .NET 云原生架构师训练营(权限系统 代码重构)--学习笔记
目录 模块拆分 代码重构 模块拆分 代码重构 AuthenticationController PermissionController IAuthorizationMiddlewareResultH ...
随机推荐
- java 访问 太平洋网ip接口,解决前端js 跨域访问失败问题
前端 js访问太平洋网IP接口地址,返回结果是403 服务器拒绝处理异常, 于是,想到了使用 服务器端访问,然后再将查询结果返回的前端 这是Java的测试源码,[具体的contronller端源码懒得 ...
- reduce/reduceRight
使用 reduce 和 reduceRight 方法可以汇总数组元素的值,具体用法如下: reduce function appendCurrent (previousValue, currentVa ...
- 浅谈xss漏洞
0x00 xss漏洞简介 XSS漏洞是Web应用程序中最常见的漏洞之一.如果您的站点没有预防XSS漏洞的固定方法, 那么很可能就存在XSS漏洞. 跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Scr ...
- 在 python 项目中如何记录日志
一. 概述 写本文的目的是我在写 python 项目的时候需要记录日志,我忘记怎么处理了,每次都需要去网上查一遍,好记性不如烂笔头, 这里把查阅的内容记录下来,方便以后查找. python 项目中记录 ...
- 贝塞尔曲线(面)二三维可视化(Three+d3)
贝塞尔曲线(面)二三维可视化(Three+d3) 在学完 games101 几何后开始实践,可视化贝塞尔曲线 我想实现三维的贝塞尔曲线,用 threejs,但是 threejs 控制太麻烦了,因此,我 ...
- idea环境下SpringBoot Web应用引入JSP
1. 环境 开发环境:idea2019.3 jkd版本:1.8 springboot版本:2.6.2 2. 引入JSP的步骤 2.1 新建工程,引入依赖 这里只是解析jsp,因此只需要引入spring ...
- jsp标签问题
在jsp页面使用标签过程中有时候不注意规则的话,eclipse会提示一些错误,下面针对这些错误提出相应的解决办法:<form></form>标签1. Invalid locat ...
- golang中的channel
1. 概念 单纯的将函数并发执行是没有意义的,函数与函数之间需要交换数据才能提现并发执行函数的意义虽然可以使用共享内存来进行数据的交换,但是在共享内存在不同的goroutine中容易发生竟态问题,为了 ...
- ansible roles实践——安装java
[root@master] /etc/ansible$ cat roles/java/tasks/main.yml ---- name: unzip jdk unarchive: src=jdk-8u ...
- 不难懂-----redux
一.flux的缺陷 因为dispatcher和Store可以有多个互相管理起来特别麻烦 二.什么是redux 其实redux就是Flux的一种进阶实现.它是一个应用数据流框架,主要作用应用状态的管理 ...