.Net通过EFCore和仓储模式实现统一数据权限管控并且相关权限配置动态生成

基于EFCore实现统一数据权限管控

在.NET应用中,通过EFCore和仓储模式实现数据权限管控,可以按照以下方式设计:

数据权限层级定义

数据权限通常分为四个层级:所有数据、本部门数据、本部门及下属部门数据、本人数据。通过仓储模式可以统一封装这些查询逻辑。

具体实现可参考NetCoreKevin的Kevin.EntityFrameworkCore.Repository`和kevin.Permission服务模块:实现统一数据权限管控并且相关权限配置动态生成

基于NET构建的现代化AI智能体Saas企业级架构: 项目地址:github:github.com/junkai-li/N... Gitee: gitee.com/netkevin-li...

基础仓储接口设计

定义基础仓储接口,包含数据权限过滤方法:

csharp 复制代码
public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    IQueryable<T> GetByDepartment(int departmentId);
    IQueryable<T> GetByDepartmentWithChildren(int departmentId);
    IQueryable<T> GetByUser(int userId);
}

实现数据权限过滤

在具体仓储实现中,通过EFCore的查询表达式实现不同级别的数据过滤:

csharp 复制代码
public class Repository<T> : IRepository<T> where T : class, IDataPermission
{
    private readonly DbContext _context;
    private readonly ICurrentUser _currentUser;

    public Repository(DbContext context, ICurrentUser currentUser)
    {
        _context = context;
        _currentUser = currentUser;
    }

    public IQueryable<T> GetAll()
    {
        return _context.Set<T>().AsQueryable();
    }

    public IQueryable<T> GetByDepartment(int departmentId)
    {
        return _context.Set<T>().Where(x => x.DepartmentId == departmentId);
    }

    public IQueryable<T> GetByDepartmentWithChildren(int departmentId)
    {
        var departmentIds = GetChildDepartmentIds(departmentId);
        return _context.Set<T>().Where(x => departmentIds.Contains(x.DepartmentId));
    }

    public IQueryable<T> GetByUser(int userId)
    {
        return _context.Set<T>().Where(x => x.CreatedBy == userId);
    }

    private List<int> GetChildDepartmentIds(int parentId)
    {
        // 递归获取所有子部门ID
    }
}

实体接口设计

定义数据权限相关实体接口,确保实体包含必要字段:

csharp 复制代码
public interface IDataPermission
{
    int DepartmentId { get; set; }
    int CreatedBy { get; set; }
}

动态权限查询扩展

创建扩展方法,根据用户权限动态选择查询范围:

csharp 复制代码
public static class RepositoryExtensions
{
    public static IQueryable<T> WithDataPermission<T>(this IRepository<T> repository, DataPermissionLevel level) 
        where T : class, IDataPermission
    {
        switch(level)
        {
            case DataPermissionLevel.All:
                return repository.GetAll();
            case DataPermissionLevel.Department:
                return repository.GetByDepartment(currentUser.DepartmentId);
            case DataPermissionLevel.DepartmentWithChildren:
                return repository.GetByDepartmentWithChildren(currentUser.DepartmentId);
            case DataPermissionLevel.Owner:
                return repository.GetByUser(currentUser.UserId);
            default:
                throw new ArgumentOutOfRangeException();
        }
    }
}

权限枚举定义

定义数据权限级别枚举:

csharp 复制代码
public enum DataPermissionLevel
{
    All,
    Department,
    DepartmentWithChildren,
    Owner
}

使用示例

在服务层或控制器中使用数据权限过滤:

csharp 复制代码
public class EmployeeService
{
    private readonly IRepository<Employee> _repository;
    private readonly ICurrentUser _currentUser;

    public EmployeeService(IRepository<Employee> repository, ICurrentUser currentUser)
    {
        _repository = repository;
        _currentUser = currentUser;
    }

    public List<Employee> GetEmployees(DataPermissionLevel level)
    {
        return _repository.WithDataPermission(level).ToList();
    }
}

权限控制中间件

可以创建中间件自动设置当前用户的数据权限级别:

csharp 复制代码
public class DataPermissionMiddleware
{
    private readonly RequestDelegate _next;

    public DataPermissionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, ICurrentUser currentUser)
    {
        // 根据用户角色设置数据权限级别
        currentUser.DataPermissionLevel = GetPermissionLevelFromClaims(context.User);
        
        await _next(context);
    }
}

这种实现方式通过仓储模式统一了数据权限控制逻辑,使业务代码无需关心具体权限实现细节,只需指定权限级别即可自动过滤数据。

相关推荐
计算机毕设VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
没差c3 小时前
springboot集成flyway
java·spring boot·后端
三水不滴3 小时前
Redis 过期删除与内存淘汰机制
数据库·经验分享·redis·笔记·后端·缓存
笨蛋不要掉眼泪4 小时前
Spring Boot集成LangChain4j:与大模型对话的极速入门
java·人工智能·后端·spring·langchain
念丶小宇6 小时前
Github上传大文件
github
sheji34167 小时前
【开题答辩全过程】以 基于SpringBoot的疗养院管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
短剑重铸之日7 小时前
《设计模式》第六篇:装饰器模式
java·后端·设计模式·装饰器模式
码界奇点8 小时前
基于Flask与OpenSSL的自签证书管理系统设计与实现
后端·python·flask·毕业设计·飞书·源代码管理
代码匠心9 小时前
从零开始学Flink:状态管理与容错机制
java·大数据·后端·flink·大数据处理
分享牛9 小时前
LangChain4j从入门到精通-11-结构化输出
后端·python·flask