.NET 云原生架构师训练营(权限系统 代码实现 EntityAccess)--学习笔记
目录
- 开发任务
- 代码实现
开发任务
- DotNetNB.Security.Core:定义 core,models,Istore;实现 default memory store
- DotNetNB.Security.EntityAccess:扫描 entities;添加 ef savechanges interceptor

代码实现
我们现在已经通过 ActionResourceProvider 完成了 action 的扫描,生成了 ResourceModel,需要持久化到 IResourceStore,持久化之后才可以将它们绑定到用户,角色
由于 ActionAccess 是一个类库,提供了一些比较零散的功能,所以需要添加一个扩展方法把功能组装起来,在 host 启动的时候执行 action 的扫描
using Microsoft.Extensions.DependencyInjection;
namespace DotNetNB.Security.Core.Extensions
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddSecurity(this IServiceCollection services)
        {
            services.AddHostedService<ResourceProviderHostedService>();
            return services;
        }
    }
}
ResourceProviderHostedService 继承自 IHostedService,有一个 StartAsync 和一个 StopAsync 方法
using Microsoft.Extensions.Hosting;
namespace DotNetNB.Security.Core
{
    public class ResourceProviderHostedService : IHostedService
    {
        public async Task StartAsync(CancellationToken cancellationToken)
        {
        }
        public async Task StopAsync(CancellationToken cancellationToken)
        {
        }
    }
}
新建一个示例的 api 项目 DotNetNB.WebApplication,在这个 api 项目里面使用我们的 dll 要足够简单,就像使用 asp .net core 的 api 一样
添加 DotNetNB.Security.Core 的项目引用之后,可以直接在 Program.cs 中调用扩展方法
using DotNetNB.Security.Core.Extensions;
...
builder.Services.AddSecurity();
在启动扫描的时候,Security.Core 并不知道外部的 host 里面有哪些 action provider,所以需要注册进来,需要构建一个 builder
同时需要一个配置 options 告诉我们它是来自哪个包,是 ActionAccess,还是 EntityAccess
参照 MvcOptions
builder.Services.AddControllers(options => {});
它是一个 Action 的委托
public static IMvcBuilder AddControllers(
  this IServiceCollection services,
  Action<MvcOptions>? configure)
{
  IMvcCoreBuilder builder = services != null ? MvcServiceCollectionExtensions.AddControllersCore(services) : throw new ArgumentNullException(nameof (services));
  if (configure != null)
    builder.AddMvcOptions(configure);
  return (IMvcBuilder) new MvcBuilder(builder.Services, builder.PartManager);
}
于是乎我们在 AddSecurity 添加一个入参
public static IServiceCollection AddSecurity(this IServiceCollection services, Action<SecurityOption>? configure)
SecurityOption
using Microsoft.Extensions.DependencyInjection;
namespace DotNetNB.Security.Core.Extensions
{
    public class SecurityOption
    {
        public IServiceCollection Services { get; set; }
    }
}
在调用 AddSecurity 扩展方法的时候通过 SecurityOption 进行配置,这样所有对外的 api 只需要做这一个配置就可以把两个包的所有功能引用进去
builder.Services.AddSecurity(options =>
{
    options.AddActionAccess();
    options.AddEntityAccess<DBContext>();
});
参考 MvcCoreServiceCollectionExtensions 的 AddMvcCoreServices 方法
internal static void AddMvcCoreServices(IServiceCollection services)
{
    //
    // Options
    //
    services.TryAddEnumerable(
        ServiceDescriptor.Transient<IConfigureOptions<MvcOptions>, MvcCoreMvcOptionsSetup>());
    ...
}
在 ActionAccess 中添加一个扩展方法 AddActionAccessControl,将 IResourceProvider 添加进去,这样就可以在 ResourceProviderHostedService 中读取到
using DotNetNB.Security.Core;
using DotNetNB.Security.Core.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace DotNetNB.Security.ActionAccess
{
    public static class SecurityOptionExtensions
    {
        public static SecurityOption AddActionAccessControl(this SecurityOption option)
        {
            option.Services.TryAddEnumerable(ServiceDescriptor.Transient<IResourceProvider, ActionResourceProvider>());
            return option;
        }
    }
}
在 ResourceProviderHostedService 的构造函数中读取 IServiceProvider
using Microsoft.Extensions.Hosting;
namespace DotNetNB.Security.Core
{
    public class ResourceProviderHostedService : IHostedService
    {
        private readonly IServiceProvider[] _serviceProviders;
        public ResourceProviderHostedService(IServiceProvider[] serviceProviders)
        {
            _serviceProviders = serviceProviders;
        }
        public async Task StartAsync(CancellationToken cancellationToken)
        {
        }
        public async Task StopAsync(CancellationToken cancellationToken)
        {
        }
    }
}
在 EntityAccess 中同样添加一个扩展方法 AddEntityAccessControl
using DotNetNB.Security.Core;
using DotNetNB.Security.Core.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace DotNetNB.Security.EntityAccess
{
    public static class SecurityOptionExtensions
    {
        public static SecurityOption AddEntityAccessControl(this SecurityOption option)
        {
            option.Services.TryAddEnumerable(ServiceDescriptor.Transient<IResourceProvider, EntityResourceProvider>());
            return option;
        }
    }
}
EntityResourceProvider 继承 IResourceProvider
using DotNetNB.Security.Core;
using DotNetNB.Security.Core.Models;
namespace DotNetNB.Security.EntityAccess
{
    public class EntityResourceProvider : IResourceProvider
    {
        public async Task<IEnumerable<Resource>> ExecuteAsync()
        {
            return new List<Resource>();
        }
    }
}
完成之后在 DotNetNB.WebApplication 中添加项目引用,就可以进行配置
builder.Services.AddSecurity(options =>
{
    options.AddActionAccessControl()
        .AddEntityAccessControl();
});
后面再完善 AddEntityAccessControl 加入 DBContext
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 云原生架构师训练营(权限系统 代码实现 EntityAccess)--学习笔记的更多相关文章
- .NET 云原生架构师训练营(建立系统观)--学习笔记
		目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ... 
- .NET 云原生架构师训练营(对象过程建模)--学习笔记
		目录 UML OPM OPM优化 UML 1997年发布UML标准 主要域 视图 图 主要概念 结构 静态视图 类图 类.关联.泛化.依赖关系.实现.接口 用例视图 用例图 用例.参与者.关联.扩展. ... 
- .NET 云原生架构师训练营(设计原则&&设计模式)--学习笔记
		目录 设计原则 设计模式 设计原则 DRY (Don't repeat yourself 不要重复) KISS (Keep it stupid simple 简单到傻子都能看懂) YAGNI (You ... 
- .NET 云原生架构师训练营(责任链模式)--学习笔记
		目录 责任链模式 源码 责任链模式 职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无需关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了 何时使用:在处理 ... 
- .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 云原生架构师训练营(权限系统 代码实现 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 ... 
随机推荐
- python 中的省略号
			在查看django源码时遇到下列内容:sweat: 这个省略号是什么意思? 来自为知笔记(Wiz) 
- 深入谈谈 Java IOC 和 DI
			1.前言 不得不说, IOC和DI 在写代码时经常用到.还有个就是在面试时 ,面试官老喜欢问 IOC 和DI是什么的问题,都快被问吐了, 可是,仍然会让许多人说的支支吾吾. 为什么? 第一,因为这个知 ... 
- 移动端position:fixed 解决方案
			相信不少人做移动端项目的时候都会遇到position:fixed 的坑. 下面提供一个解决方法,不用引入任何其他的js库,纯css解决. 解决问题的关键就是:fixed元素内部必须嵌套一个positi ... 
- .Net 线程安全集合
			.Net 提供了基于生产-消费模式的集合类,这些集合对多线程访问安全,定义在System.Collections.Concurrent名称空间中.这个名称空间中包括基础接口IProduceConsum ... 
- Java库中的LocalDate类
			Java库中的LocalDate类 类库设计者决定将保存时间与给时间点命名分开.所以标准Java类库分别包含了两个类:一个用来表示时间点的Date类:另一个是用来表示大家熟悉的日历表示法的LocalD ... 
- 【Java】多线程入门
			Java多线程学习(入门) 前言 目前对于线程的了解仅仅停留在学习python的threading库,很多线程的概念没有真正弄清楚,所以选择来系统性的学习多线程.那么这次选择的是Java的多线程学习, ... 
- linux下编译支持opencl的opencv for android
			主要的步骤其他人已经写过,请参考这篇:https://www.cnblogs.com/hrlnw/p/4720977.html 操作的细节请参考附件的pdf: https://files.cnblo ... 
- 使用VS Code的MySQL扩展管理数据库
			我将在本文告诉你如何用VS Code的扩展程序管理MySQL数据库,包括连接到MySQL.新建数据库和表.修改字段定义.简单的查询方法以及导入导出. 在许多情况下,我们需要随时查看数据库的记录来确保程 ... 
- linux中sed命令(全面解析)
			目录 一:linux中sed命令介绍 1.sed作用 2.sed命令格式 3.参数 4.sed的编辑模式 5.sed参数解析用法 二:sed 参数 -f 案例实战解析 1.前介 2.引入简介 3.方法 ... 
- JVM调优方法
			目 录 目 录 I 诠释JVM调优 1 第1章 JVM内存模型及垃圾收集算法 1 1.1 根据Java虚拟机规范,JVM将内存划分为 1 1.2 垃圾回收算法 1 第2章 内存泄漏及解决方法 2 2. ... 
