基于EntityFramework的权限的配置和验证

1.   概要

本文主要介绍公司现有系统框架的权限体系,和一些待扩展功能的说明。目前该权限体系基于角色构建(RBAC),原则上,系统中不允许出现对用户、组织等其他对象指派权限的情况。

2.   权限分类

目前系统中的所有表现形式的权限可以归为两类:

一类是描述对象或动作是否可见,我们称之为功能权限(Authority)。例如,菜单的可见性、用户添加按钮是否可见、用户添加方法是否可用等;

另一类是描述可见对象的范围或动作的影响范围,我们称之为数据权限(Permission)。例如,未成年用户列表、行政区域内数据操作限制等。

说明,这里authority和permission并不是取英文原意,只是用于程序简化权限对象命名,实际对应的应该是Function Permission 和 Data Permission。

2.1. 功能权限

功能权限的定义通常都可以序列化存入数据库。因此,在设计数据库表时,它和用户、角色的关系是这样的:

权限和角色、角色和用户都是多对多的关系,需要建立中间表来存储。

2.2. 数据权限

数据权限的定义大多数情况下难以序列化存入数据库。因此,在设计数据库表时,只需要记录它和角色的关系即可:

3.   实现过程

从用户的角度来说,他们只关心系统配置好之后是否符合实际业务逻辑,少数用户会主动参与到配置过程。

3.1. 配置

配置主要做了两件事情,一是定义权限,二是授权。

功能权限和数据权限的授权并没有什么区别,从数据表来看,可以简单的理解为对Role2Authority和Role2Permission表的数据改动;从界面上来看,如图

菜单权限是功能权限的一种表现形式。

3.1.1.   功能权限的定义

而定义则有较大的不同,功能权限可以在没有确定管理对象的情况进行定义,而且从实际的情况来看,系统的功能或界面设定并不完全和系统管理对象一一对应,功能权限更多的情况是对系统需求的描述。

例如,我们计划在系统中增加工程对象管理功能,这时可以快速在Authorities表中加入一个菜单权限,用于控制用户是否可以访问工程对象管理页面project.html,而此时,project.html页面可能还未开发完成,但并不影响权限的定义。另一方面,该权限定义的动作中涉及的对象可能不止工程对象,而是由多个对象操作结合完成的操作;因此,功能权限的定义应该尽量按照用户需求最小单元来划分。

3.1.2.   数据权限的定义

动态定义

数据权限的定义,目前只实现了预定义,即编码阶段的定义。数据权限授权界面所看到的可选项均为编码预设的内容。

如果想要在运行时,动态定义数据权限,例如,项目权限中的部门项目,它的定义内容为当前登录用户可以查看本部门的项目,这是对项目对象的一个范围限制。使用SQL语句,可以描述为

SELECT * FROM Projects WHERE OrgId=(SELECT OrgId FROM Users WHERE Id=@UserId)

这里可以在数据库中建立一个Permissions表,将上面这条SQL语句的条件部分命名为部门项目,并给定编号3002,存入表中;然后建立Permissions表和Role2Permissions表的外键关系实现数据权限的动态配置化,但具体操作下来,会发现很多问题。

首先,联表查询时,条件语法是有变化的;其次,动态配置需要有配置界面,在界面上录入SQL语句是不安全的,而且用户很可能并不了解SQL语法;在一些管理权限框架中,也有使用条件表达式生成器简化定义过程,这是可以尝试的方向。

而本文描述的系统中,数据层采用的是EntityFramework框架,因此无法使用SQL语法来实现动态定义数据权限。或许在对lambda表达式有了足够了解后,可以尝试通过文本建立lambda表达式,从而实现动态定义数据权限。

预定义

对于部门项目权限系统采用的是lambda描述

Formula = oper => (pro => pro.Organizations.Contains(oper.Organization));

其中oper为用户参数,pro为项目参数。数据权限的预定义内容存放在类中,并为此建立新的类库项目,称为权限库。当系统需要新的数据权限时,可以只修改权限库,生成部署文件,替换运行时环境中的部分文件达到数据权限配置化的目的。

上述表达式Formula只是数据权限对象的一个属性。数据权限名称可以定义为部门项目,编号为3002,这样可以和Role2Permissions表中的PermissionId对应起来,实现对角色的授权。

3.2. 验证

3.2.1.   功能权限的验证

对于本文描述的B/S系统,功能权限的验证可分为服务端和客户端两个不同实现。

首先,服务端的实现需要拦截所有请求,并根据会话中用户的角色、请求的资源,逐一匹配权限定义规则,实现验证。

例如,所有Handler接口都继承自一个父类,并在父类中进行验证。

客户端的实现则是隐藏用户没有权限的菜单或按钮。对于使用后台脚本语言的页面,可以使用用户角色下的权限集合很方便的进行控制;而纯html前段,则可以考虑首先隐藏所有涉及权限的元素,再通过ajax获取权限集合,显示可以访问的元素。

需要注意的是,服务端验证是必须要实现,以保证权限系统的可靠性。

3.2.2.   数据权限的验证

与功能权限不同的是,数据权限主要是对数据范围的控制;因此,验证过程最终会在系统数据层实现。这里有两种实现方式:一是只读验证,另一种是读写验证,各自有优缺点。

只读验证的方式如下面这个方法:

这是一个API查询方法,其中condition、verCondtion、attCondition是针对三个对象的数据权限,通过这个查询方法,用户将只能得到他可以查看的Project对象及子对象数据。

类似的,分页查询、视图查询等查询方法,除了用户输入的条件,还需加入PermissionManager提供的数据权限条件,最终交给业务层查询。这种方式的缺点在于,用户可能使用查询权限以外的数据,伪造修改和删除操作。

读写验证除了查询方法需要添加额外权限条件,修改和删除也要先进行数据可读性查询验证。因此,相对而言,读写验证的安全性是最高的,但性能则要比只读查询差很多。

3.2.3.   一些细节

条件的合并,PredicateBuilder是专门用于lambda条件表达式合并的工具。通常数据权限条件和用户查询条件应该使用And操作。

集中管理数据权限的验证,上述在API方法中使用PermissionManager获取数据权限条件的方式是有一些缺点的,例如,这要求所有编码人员都了解权限验证的过程,也有遗漏的可能导致数据操作不受控制。对于使用EF框架的系统,可以考虑在DbContext中集成权限验证过程。

具体的验证过程,创建一个通用的验证方法,使用当前用户作为参数,返回相关对象的过滤条件。由于数据权限是建立在对象基础上的,因此该验证方法最好使用泛型。方法将分析用户的所有角色,以及每个角色下的数据权限授权编号,并根据授权编号从预定义库中取出所有相关lambda表达进行Or或者And组合。组合方式取决于多角色权限重合的处理策略。

4.   遗留问题

最后,本文虽然到此,但基于EF框架的权限开发还有一些问题尚未解决。例如,动态定义数据权限,权限读写验证的效率问题,数据权限的集中验证等,希望自己有时间继续完善。

本文仅在博客园发布,转载请注明出处。

时间: 2024-12-14 07:35:53

基于EntityFramework的权限的配置和验证的相关文章

Forms身份验证和基于Role的权限验证

Forms身份验证和基于Role的权限验证 从Membership到SimpleMembership再到ASP.NET Identity,ASP.NET每一次更换身份验证的组件,都让我更失望.Membership的唯一作用就是你可以参考它的实现,它的数据库创建和扩展方面就真的让人实在无法使用了. 当大家欢呼着让ASP.NET开发走上ASP MVC的正确道路时,身份验证组件却走的更远了:SimpleMembership除了第三方验证的参考价值,它的主键和对领域模型的入侵让它成了摆设,而ASP.NE

NFS服务的基本配置及验证

NFS服务的基本配置及验证 一.NFS的用途   NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,NFS允许一个系统在网络上与他人共享目录和文件.通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件. 二.NFS的安装 NFS安装的前提是:安装rpcbind和nfs-utils软件包. 分别在客户机和服务器上安装rpcbind和nfs-utils软件包. 检查软件是否安装成功. 三.NFS的配置步骤 基于

基于角色的权限管理系统

我们开发业务系统的时候,基本上都会涉及到权限管理模块,要求不同的人看到不同的菜单,操作不同的按钮,看到不同的数据.很多初学者面对这样的需求不知道如何下手,特别是稍微复杂点的权限,更是找不到方向,为此我们夜鹰教程网特别推出了这套基于角色的权限管理视频教程,通过给用户分配角色,给角色分配权限,来实现权限管理.这样一来,可以实现不同的人管理不同的菜单,操作不同的按钮,看到不同的数据.可以划分权限组,每个组的成员拥有相同的权限.也可以把同一个人分配到不同的权限组,具有多个权限组的权限,实现权限的组合.

vsftpd的基于pam_mysql的虚拟用户配置示例      

第一步:安装vsftpd和mariadb ~]# yum install mariadb-server ~]# yum install vsftpd 因为中CentOS 7平台上/lib64/security/中没有pam_mysql模块驱动,需要编译安装pam_mysql这个模块. 准备编译环境 安装Development Tools 和 service platform Development这两个包组,另外需要安装依赖到的开发包pam-devel,openssl-devel,mariadb

SVN版本库(访问权限)配置实例笔记

http://blog.csdn.net/zjianbo/article/details/8578297 SVN版本库(访问权限)配置实例笔记 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/ex_net/article/details/8578297 作者:张建波 邮箱: [email protected] 电话:13577062679 欢迎来电交流! 访问控制如图所示 说明: why用户仅仅只能访问(读写)yjb目录,对其它目录是无法“查看

asp.net权限控制配置web.config

项目下 有三个文件夹 A,B,C 验正方式是 Forms 验正 我要设置他们的访问权限为, A,匿名可访问 B,普通用户授权后才能访问 C,只允许管理员访问 <configuration> <location path= "A "> <system.web> <authorization> <allow users= "* "/> </authorization> </system.web

Service系统服务(六):rsync基本用法、rsync+SSH同步、配置rsync服务端、访问rsync共享资源、使用inotifywait工具、配置Web镜像同步、配置并验证Split分离解析

一.rsync基本用法 目标: 本例要求掌握远程同步的基本操作,使用rsync命令完成下列任务: 1> 将目录 /boot 同步到目录 /todir 下   2> 将目录 /boot 下的文档同步到目录 /todir 下   3> 在目录 /boot 下新增文件 a.txt,删除 /todir 下的子目录 grub2,再次同步使 /todir 与 /boot 一致   4> 验证 -a.-n.-v.--delete 选项的含义 方案: 本地同步操作: rsync [选项...] 本

webapi框架搭建-安全机制(三)-基于角色的权限控制

webapi框架搭建系列博客 上一篇已经完成了"身份验证",如果只是想简单的实现基于角色的权限管理,我们基本上不用写代码,微软已经提供了authorize特性,直接用就行. Authorize特性的使用方法 配置Authorize 比较简单,直接上代码 using System.Collections.Generic; using System.Net.Http; using System.Security.Claims; using System.Web.Http; using we

NFS网络文件系统服务配置、验证及错误解决

NFS网络文件系统服务配置.验证及错误解决 前期准备: 1.至少准备一台服务器(nfs-server)和一台客户机(nfs-client).老表测试用的服务器端用的系统是ubuntu,客户机用的是CentOS 6.5,所以有些地方操作不一样. 2.给两台测试机都安装NFS服务和rpc服务.(一般安装NFS服务会自动安装rpc) 安装: ubuntu:sudo apt-get install nfs-kernel-server CentOS:yum groupinstall "NFS file s