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

本文是.NET云原生架构师训练营的学习笔记,详细介绍了权限系统的开发任务和代码实现,包括定义核心模型、创建Memory和EntityFramework存储、PermissionStore和ResourceStore的实现。同时,讲解了如何在ResourceProviderHostedService中处理Permission,以及使用IPermissionStore和IResourceStore接口进行资源管理。
摘要由CSDN通过智能技术生成

目录

  • 开发任务
  • 代码实现

开发任务

  • 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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值