讨论《细粒度的Action实现系统权限》帖子

讨论《细粒度的 Action 实现系统权限》帖子

 

 

帖子地址: http://www.iteye.com/topic/10400?page=1

 

关键字: Action ,细粒度权限,实例权限, Module RBAC queryString Acigi Voter

 

引题

Struts WebWork 这样的系统中,会按照每个细粒度功能定义 Action 。比如:

客体(资源)

Action

功能

用户

ListUserAction

查询用户

RemoveUserAction

删除用户

ModifyUserAction

修改用户信息

CreateUserAction

添加用户

 

看!这样 Action 就相当于客户(资源)+操作了!!!

Action 使用 RBAC 策略,就可以控制某些用户能增、删、改和查,而另一些却只能查、改等等权限。

eway 说“笔者 eway 已经在一个小项目中采用了这个办法,效果还好。不妨试试,说不定收到意象不到的好处。”

讨论

定义 Module 抽象层

robbin 说“用户管理功能可能要对应六七个相关的 Action…… 所以我觉得在 Action 上面再抽象出来一层 Module ,针对 Module 设置权限比较好。”

分组概念

jjw 说道“ 分组概念 ( 分组也是一棵树,用户就是这里的叶子 )
只有角色是不够的, B 公司发现 A 有财务问题成立了一个财务调查小组 , 然后我们赋予了这个小组财务调查员的角色 ( 注意是赋予小组这个角色 ). 这样这个小组的所有人员
都有财务调查的资格。而不需要给小组的每个人都赋予这个角色 ( 实际上已经拥有了 ) ,分组概念也适合部门,因为任何一个部门在公司里或者社会上都在扮演着一个泛的角色。”

定义接口,注入 SecurityService

思想如下:需要权限判断的 Action ,必须实现 Protected ,以便和不需要权限判断的 Action 区别开。 Protected 定义了权限判断方法, Action 必须实现该方法。

 

权限判断执行过程由:拦截器完成。拦截器拦截 Action ,对实现 Protected 接口的 Action 进行判断。而具体判断逻辑由 Action 定义的。

 

下面,继续研究一下: Action 如何实现权限判断逻辑。

有这样一个服务: SecurityService 含有方法: boolean hasPermission( User user, String someTokenString )

所以 Action 里面的权限判断几乎是 Delegate SecurityService SecurityService 可以使用动态注入的方式,达到可替换 SecurityService 的实现模式。

 

QuakeWang 继续给出了“更细粒度的控制,或者是一些特殊逻辑权限检查”。这些手段直接在 Action 里面编码。比如:

 

!group.getName();.equals("ADMIN_GROUP"); && securityService.hasPermission(RemoteUser.get();, "maintain_group");; 
 

 

queryString 是否属于权限控制范围

eway 说“我怎么觉得诸如 queryString 之类的权限控制不应在权限系统实现,基本上是个业务实现的问题。我觉得这个 queryString 往往是代表了 什么情况下 这个权限有效的问题,如果都考虑进入权限系统的话,权限系统会非常庞大,难以维护。这种权限生效的 “situation” 的问题,我往往做到 业务逻辑层中去 check 。”

eway 继续说“偶还是觉得用 资源 + 操作 去思考权限的粒度比较合适?比这个粒度粗的权限,就用角色来实现,比这个粒度细的权限就用业务实现。这样权限系统比较适中。”

 

jackyz 举例说明“如果要精确控制 , 必须要在比 Action 更细的层次做 . 举例来说 :
论坛的帖子显示界面 , 如果当前用户对当前帖子 有删除权限 , 则显示删除链接 . 否则 , 就不显示 .
当前的操作 (Action) 是显示帖子 , 但是显示链接的逻辑判断需要对另外一个功能 ( 删除功能 ) 进行判断 . 这个判断是业务的必须 , 没有办法省略 .

 

ruby 说这样会导致 Action 不纯粹。 ruby 说“如果这样来写 ACTION, Action 也太不 " 纯粹 " , 包含了太多和当前 action 无关的逻辑 , 既然是要进行界面元素的显示控制 , 就在界面上控制 好了 , 比如用 taglib, 至于权限列表 , 保存在 session, 显示界面元素时时取出对比一下 , 有此权限就显示此界面元素 , 没有就不显示 .

 

jackyz 指出确实不纯粹,但确实有必要,而且还提出了“权限引擎” 概念。他说“确实不纯粹 . 但是 , 对于实例级别的权限控制 , 似乎没有更好的办法 .

首先 , 明确一下 . 这里的需求是 : 实例级的权限控制 ( 就是控制到谁对什么资源 [ 的哪一个实例 ] 具有什么操作 ). 而不是功能级的权限控制 ( 就是控制到谁对什么资源 [ 不管哪一个实例都 ] 具有什么操作 ).
实例级的权限控制 , 比如 ,A 用户可以删除 A 帖子 , 但不能删除 B 帖子 . 它与具体资源的实例相关 .
功能级的权限控制 , 比如 ,A 用户可以删除帖子 (A 用户具有删除帖子的权限 , 不管什么帖子 ). 它与具体资源的实例无关 .
功能级的权限控制 , 与用户和资源类型相关 , 对于特定的用户来说 , 枚举资源类型得到的列表是确定的 , 确实可以用 Session 保存列表 , 在显示逻辑中处理 . 但是 , 实例级的权限控制 , 与具体的实例相关 , 对特定的用户 , 不可能枚举所有资源的实例 .

这种情况下 , 只有 Action 的处理过程本身能够确定对于特定实例 (ArticleId=xxx) 做出权限判断 .

从另一个角度来看 , 这里的 Action 实际上是一个 " 交互层 ", , 它服务于显示逻辑 , 显示逻辑需要一个 " 是否可以删除 " 的属性 , 那么它就应该提供 , 不管是从 Session 来取 . 还是从权限引擎来运算 , 这是另外一个问题 .

 

后来又引入了 Acegi ,先按下不表,稍后再议。

权限控制切入点

仅仅在 url 层进行控制显然不够,因为这样可以采用手工输入 url 地址来侵入系统。即便模仿“ C/S ”风格,不显示地址栏也不行。地址栏用户还是可以调出来的。

所以不仅要控制前台显示“链接”,“按钮”等要素,还要对后台方法进行拦截,做权限判断。

 

nihongye 引入 Acegi ,她 [ 不知道是否为女士,我根据头像判断的 ] 说道“如 acegi: 权限控制可以分前后两部分来做 . 前的可以基于 url 来做 . 后的基于方法拦截来做 . 前后的结合通过 runAsManager 来做到 . 例子就是里面的 contact. 后台的可以定义粗粒度的控制资源 , 前台再细化 . 并且分开开发 , 保证前后台的开发无关 .

nihongye 继续谈了 Voter acegi 提供了可配置的 voter, 一个验证请求交由多个 voter 进行处理 , 已经提供了 roleVoter. 可以加入自定义的 voter 来处理 .

 

按照角色判断,可以由 roleVoter 验证,还可以自定义自己的 Voter Spring 应该还定义了其他一些 Voter ,以方便开发者。

 

其他观点

还有其他一些观点,我没有领悟到要领,在此不表。抱歉!

 

分析

相关定义

(仅供参考,选自 XACML http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml

Resource (资源) - Data, service or system component

Subject (主体) - An actor whose attributes may be referenced by a predicate

XACML 规范非常牛气,也很强大。 Oracle Entitlement Server 遵守了这个规范。

 

我们一般称呼请求者为“用户”,规范里面称呼为“主体”。“主体”可以是用户、程序、计算机等。

“资源”大多情况下是我们指的数据、服务或者某个应用组件。

细粒度属于权限

细粒度,帖子里面也被称为对一个“实例”的权限。 XACML整个规范围绕细粒度权限展开的。

我也认为这是属于权限范畴。举例来说:用户只能编辑自己发出的帖子;版主可以编辑自己管理版面的任何帖子。

这就涉及到权限判断啊。当然属于权限领域。只是目前大多系统没有好的模型来控制这件事情,采用硬编码罢了。

 

当然,细粒度权限和业务逻辑紧密关联。但仍然应该隶属于权限范畴。

权限分类

目前我们遇到如下需求了:

1.         界面哪些功能菜单要显示出来;

2.         调用 Action url 需要再次判断用户功能权限;

3.         界面哪些按钮要显示出来,哪些链接要显示出来;

4.         调用后台某方法,需要先做权限判断;

5.         细粒度权限, queryString 等如何判断;

6.         界面比如某个下拉框显示内容,如何取出。比如机构下拉框,总公司用户登录,机构下拉框显示各个分公司机构;分公司用户登录,下拉框显示本分公司下属机构。

 

综上,可以将权限分为:

1.         功能级权限, url,action, 菜单隶属此类 ;

2.         细粒度权限,这个又可以分为:

a)         决策权限,比如某用户(按照规范称为主体)请求删除某条数据,应该做出权限判断,是否允许该用户删除。界面按钮、链接是否显示属于此类,调用后台方法(如删除客户资料方法)也隶属此类。

b)        查询权限。界面显示下拉框内容,查询数据都属于此类。系统应该返回某用户(主体)具有权限查看的数据有哪些。比如,总公司人员登录,返回分公司列表,以便前台页面展示到下拉框;分公司人员登录,返回本分公司下属机构类别,以便前台页面展示到下拉框。

 

业内产品、规范

业内最牛气的规范,是 XACML eXtensible Access Control Markup Language )。

(http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml

 

国际产品:

Oracle Entitlement Server

http://www.oracle.com/technology/products/id_mgmt/oes/htdocs/fov_entitlements_server.html 并购 BEA 后,属于 Oracle 了。很强大的哦。

  IBM Tivoli Access Manager

http://www-01.ibm.com/software/tivoli/products/access-mgr-e-bus/

本土产品:

Metadmin Access Manager (效方为安,北京)

http://www.metadmin.com

开源社区产品: Spring Security (源于 Acegi )。

http://static.springframework.org/spring-security/site/

 

Oracle IBM 产品,采用 Policy 策略,设置细粒度权限策略。由权限服务器集中管理,可以为多个分散系统管理权限。只提供决策权限授权。有管理界面。

Metadmin 产品,也采用 Policy 策略,设置细粒度权限策略。目前以中间件模式集成到应用系统,提供权限服务。提供决策权限和查询权限两种权限授权。设置权限策略,完全界面化,无需编码和 XML 配置。

 

Spring Security 我只了解皮毛,少讲一些免得引起误解) Spring Security 提供了框架,开发人员可能需要自己定制 Voter ,还要书写大量的 XML 配置文件。( Spring 的配置文件,确实。。。。。。)

权限应该在哪层进行控制

为了达到统一和让系统简化的目的,在 Control 层控制最佳。最好可以将权限设计成中间件,可以在需要的时候,通过 API 调用。

 

(这篇文章够长的了,下次再写吧。欢迎大家讨论。)

 

作者简介:汪金保,从事权限领域开发有 5 年。目前在北京效方为安信息技术有限公司担任首席架构师职务。可以使用电子邮件 wangjbao@gmail.com 与我联系。

 

欢迎转载,转载请注明出处。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值