该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2012-07-27
george_space 写道 sunway00 写道 多角色的情况一般来说是很普遍的,很难将每一个用户的功能都抽象为角色进行单一的角色赋权。给给用户单独赋予权限是一种变通的解决办法,但是一不小很容易失控造成角色和权限的混乱。
数据权限如果有两个或更多维度的话应该如何处理呢? 比如:分地区、类型两种维度 省日化经理只能看本省范围内日化产品的销售情况,城市经理能看到本市范围全部商品的销售情况等等 如果不同的角色对于同一个功能有不同的数据范围要求,如何能设计一个良好的通用模型?。 问题很好。 大家仿佛都在提出自己遇到的问题,却没有牛人出来指点一下迷津啊。 呼唤高手快点出来分享一下你们的心得。 我觉得数据权限的查询可以进行分类组装控制这个概念,比如说 (1):你想区分地区的的差异化查询条件,那你前提是所要查询的产品属性应该具备地区的属性,然后通过日化经理的地区进行组装匹配 (2):如果说对于具体的产品销售情况的多个参数查询的权限,可以通过配置表字段权限控制机制来进行控制。如同角色控制权限一样。等等。。。 |
|
返回顶楼 | |
发表时间:2012-07-30
george_space 写道 sdnasky 写道 george_space 写道 oolala 写道 sdnasky 写道 数据模型不是关键,只要保存用户-权限关系就行了
设计上的关键是找到权限控制点 界面级:自定义标签可以实现 URL级:Filter可以实现 后台方法级:AOP可以实现 数据级:良好设计+AOP可以实现 即使没有良好的设计,针对不同需求,在控制点写拦截处理类就行了,只是重复代码的问题 权限的关键是:找到控制点,拦截,然后做你想做的事情 分析得不错
我现在也是使用自定义标签来实现的界面元素控制: <eagle:hasPermission name="saveOrder"> <input type="image" src="${rootUriOfCurrentPage}/resources/image/button/save-order.png" name="submit_top_button" id="submit_top_button" value="保存订单" /> </eagle:hasPermission> 问题:现在标签中定义拥有“saveOrder”权限的人,可以看见保存订单的按钮,但是项目交给客户以后,客户想让拥有“kissGirl”权限的人,也能看见保存订单按钮,那么你是不是要去修改页面? 这样每次权限定义发生变动,都要去修改页面自定义标签,跟硬编码写死权限判断有什么分别?
问题:怎么实现?这个是关键! 举个简单的例子: 一个列表页,要求:普通员工看见自己发表的信息(标题、发布时间); 部门经理看见本部门的信息(标题、发布时间 + 发布人积分); 管理员看见所有的信息(标题、发布时间、发布人积分 + 删除/修改)按钮。 这个列表页是使用web service从美国加利福尼亚州总部读取的,问,如何实现数据权限控制? 这样的需求,不是一个小小的AOP拦截就能够搞定的,即使能搞定,其复杂度也是超乎想象的。 有一个比较笨的方法,就是在服务端做权限逻辑判断,组装出当前权限应该看到的数据量和数据列,然后使用json 格式传递到视图层进行渲染,这样就相当于把视图端自定义标签所做的判断,移动到了服务端。 服务端使用策略模式,针对不同的权限,执行不同的查询逻辑; 如果有新的查询逻辑出来,就更麻烦了,理论上可以使用“页面上可视化配置 = > 动态生成java类 => 动态加载新的查询逻辑类 => 动态执行新的查询逻辑类”这样的方式来把新逻辑插入当前的判断中,但是这仅仅是理论上的设计,实际做起来,可不是上面这样三言两语能够“说”完的。 要做到数据权限的精确控制,除了和系统紧密耦合的做法和硬编码判断的做法,我还没有发现更好的实现,请楼下大牛们赶紧赐教。 ---------------------------------------------------- 1.标签使用错误,界面标签只是标识出该控制点的唯一标识,剩下的事情由标签处理函数去取出用户权限列表,并且判断用户是否含有该权限点的唯一标识 <eagle:hasPermission id="xxx.jsp.saveorder"> <input type="image" src="${rootUriOfCurrentPage}/resources/image/button/save-order.png" name="submit_top_button" id="submit_top_button" value="保存订单" /> </eagle:hasPermission> 权限标识可以使用命名规则,用来区分不同类型权限:菜单,界面控件,或其他的 2.取数据的方法如果设计合理,预留了可以方便添加数据过滤的接口,用AOP拦截方法调用,修改输入参数即可 即使设计不好,用AOP拦截方法调用(不调用现有方法),直接调用全新的含有数据过滤的取数据方法即可,无非是有重复代码而已 1、我的权限标签支持ant式过滤的,类似下面: <eagle:hasPermission id="user.customer.*,user.manager.*"> <input type="image" src="${rootUriOfCurrentPage}/resources/image/button/save-order.png" name="submit_top_button" id="submit_top_button" value="保存订单" /> </eagle:hasPermission> 但是问题的关键是:如果现在客户要求“user.teamleader.*”也能保存订单,你是不是要把“user.teamleader.*”手动添加到权限标签里面去?是不是要改动视图层页面?是不是跟修改硬编码也简单不到哪里去? 2、AOP方式没有亲身实践过,不知道是否行得通,不做评论。 下面是我现在的初步设计,总体的意图是将查询逻辑留给软件部署者来在界面中配置: 执行阶段时序图: 我们在设计功能权限时,也用到自定义标签。先说下我们用自定义标签是如何控制访问的。所有的标签都定义了一个功能Id,唯一标识。标签在解析时,获得登陆人所持有的ID组,和本标签的ID值匹配,有则表明有此权限,否则无。标签在控制功能元素时,可以是多种形式,如:按钮变灰不可用,或不显示。也可以控制js脚本的执行。所要做的工作就是,将这些功能点分配好Id,并保存到数据库中,这个工作只需要一次。一般在功能定义模块输入这些数据,相当于数据准备。再到功能权限页面,做权限的分配。 权限控制的是资源,首先就要知道资源的存在,如:给每个按钮一个编号,并存到数据库中。这样在权限分配页面,分配权限就是分配ID,可以做到灵活分配权限。就像菜单权限一样,菜单都会存储到数据库中,分配的时候也只是分配的menuID。 而不是将权限的分配规则先定死在标签中。 其实这也是权限分配,访问控制的两种不同的思维方式。举个简单的例子,就好明白了。如在大学教室上自习,人多位置有限,就实现了分配。两种分配方式。一种是楼主的思维。在桌子上写上人的名字,找到自己名字的就可以坐那,没找到的今天就不能在上自习。另一种思维就是:给桌子编个号,由教室管理员,发号给你。你手上有什么号,就可以坐那。一个号可以发给你,下次也可以给别人。 第一种方式,就不得不把桌上的名字换了重写,以便给其他人用。这种方式将资源和它的访问者绑定死了。 而第二中方式就要灵活得多。这种方式,资源只和编号绑定,编号再和访问者关联。只要资源和编号的对应关系不变。 编号怎么分配给访问者都可以,有点解耦的意思。 系统要做的工作,也只是编号码(一次就够了),发号码了,还可以发重复号码。 |
|
返回顶楼 | |