`

seam2.1权限验证(15.5)@Restrict注解 (三)

    博客分类:
  • Seam
阅读更多
15.6.8. 权限验证的模型(The Permission Authorization Model)seam security提供了一个可扩展的应用程序权限解析框架。下面的类图展现了权限验证框架的主要组件:



上图中涉及到的类,将在后面的章节中详细介绍。
15.6.8.1. PermissionResolver组件这个组件实际上是一个接口。提供了解析某个对象权限的方法。Seam提供了下面两个内置的PermissionResolver实现。后面的章节中会详细介绍它们。
- RuleBasedPermissionResolver - 这个权限解析器使用Drools来解析基于规则的权限验证。
- PersistentPermissionResolver - 这个权限解析器用来解析持久化的对象权限,例如将权限存储在数据库中。
15.6.8.1.1. 编写你自己的PermissionResolver自定义权限解析器非常简单。PermissionResolver接口只定义了两个必须实现的方法,这两个方法列举在下面的表格中。

表 15.7. PermissionResolver接口
- boolean hasPermission(Object target, String action):这个方法必须要判断出当前被验证的用户(通过Identity.getPrincipal()获得)是否拥有权限来对target进行某个action。如果返回true,那么当前用户拥有权限,反之返回false
- void filterSetByAction(Set<Object> targets, String action):这个方法应该实现将任意对象从指定的set中删除,以便当传入相同的action参数值的时候能够让hasPermission()方法返回true。

当你将自定义的权限解析器部署到你的项目中去的时候,它就会自动检查并注册到默认的解析器组中去。
15.6.8.2. 权限解析链ResolverChain一个权限解析链(ResolverChain)包含了一组有序的权限解析器(PermissionResolver),因此它能够解析某一特定class或者target的权限。

下面的程序表(sequence diagram)展现了在权限验证过程(流程说明)中,各权限组件是如何互相配合工作的。一个权限验证的时间有可能来自各种不同的情况,例如,通过安全拦截器、EL表达式s:hasPermission、或是显式调用Identity.checkPermission接口:


- 1. 在某个地方触发了权限验证事件(在代码中或者EL表达式中),调用到了Idengity.hasPermission()方法。
- 1.1. Identity引用PermissionMapper.resolvePermission()方法,传入需要被解析的权限。
- 1.1.1. PermissionMapper提供一个ResolverChain实例的Map,key为class。通过这个map为权限的target对象寻找一个正确的ResolverChain。
   一旦找到正确的ResolverChain,就会调用ResolverChain.getResolvers()将所有的PermissionResolver重新检索出来
- 1.1.2. PermissionMapper会为ResolverChain中的每一个PermissinResolver调用一次hasPermisson()方法,传入需要被检验的权限实例。一旦任何一个PermissionResolver返回了true,权限验证就成功并且PermissionMapper也返回true给Identity。如果没有一个PermissionResolver返回true,权限验证就失败。
15.6.9. RuleBasedPermissionResolverRuleBasedPermissionResolver作为seam内置的一个权限解析器,支持基于Drools(JBoss Rules)规则的权限判断机制。基于规则的权限验证解析器有两个重要的原因

1)、将权限验证的业务逻辑与其他部分分离,全部集中到规则文件中,便于维护与修改
2)、速度——Drools的规则判断与执行内核拥有非常高效的算法,能够让非常复杂的规则判断更加快速。

15.6.9.1. 需求(Requirement)如果使用基于规则的权限判断机制,那么以下几个包必须发布到你的项目中去:


drools-compiler.jar

drools-core.jar

janino.jar

antlr-runtime.jar

mvel14.jar

15.6.9.2. 配置首先,Drools规则系统需要在components.xml文件中配置一下。默认情况下,会去找叫做securityRules的规则。例如下面这段配置:
Xml代码

<components xmlns="http://jboss.com/products/seam/components" 
              xmlns:core="http://jboss.com/products/seam/core" 
              xmlns:security="http://jboss.com/products/seam/security" 
              xmlns:drools="http://jboss.com/products/seam/drools" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation=  
                  "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd  
                   http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd  
                   http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd"  
                   http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd"> 
    
     <drools:rule-base name="securityRules"> 
         <drools:rule-files> 
             <value>/META-INF/security.drl</value> 
         </drools:rule-files> 
     </drools:rule-base> 
    
  </components> 
<components xmlns="http://jboss.com/products/seam/components"              xmlns:core="http://jboss.com/products/seam/core"              xmlns:security="http://jboss.com/products/seam/security"              xmlns:drools="http://jboss.com/products/seam/drools"              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"              xsi:schemaLocation=                  "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd                   http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd                   http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd"                   http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd">       <drools:rule-base name="securityRules">         <drools:rule-files>             <value>/META-INF/security.drl</value>         </drools:rule-files>     </drools:rule-base>    </components>





这个默认的规则名称可通过覆盖RuleBasedPermissionResolver的security-rules属性来指定。
Xml代码

<security:rule-based-permission-resolver security-rules="#{prodSecurityRules}"/> 
<security:rule-based-permission-resolver security-rules="#{prodSecurityRules}"/>
一个RuleBase的组件已经配置好,现在是时候来写一些安全规则了。
15.6.9.3. 编写权限规则编写权限规则的第一件事就是要在你程序jar包所在路径/META-INF下面创建一个规则文件。通常这个文件被取名为类似security.drl。不过你可以随意给他取名,只要这个名字在components.xml文件中能对的上号。

那么,安全规则文件到底需要包含哪些内容呢?首先我们应该快速浏览一下Drools的文档。我们先从一个及其简单的例子来分析:
Xml代码

package MyApplicationPermissions;  
    
  import org.jboss.seam.security.permission.PermissionCheck;  
  import org.jboss.seam.security.Role;  
    
  rule CanUserDeleteCustomers  
  when  
    c: PermissionCheck(target == "customer", action == "delete")  
    Role(name == "admin")  
  then  
    c.grant();  
  end 
package MyApplicationPermissions;    import org.jboss.seam.security.permission.PermissionCheck;  import org.jboss.seam.security.Role;    rule CanUserDeleteCustomers  when    c: PermissionCheck(target == "customer", action == "delete")    Role(name == "admin")  then    c.grant();  end
让我们一行一行来分析。首先我们看见的是包声明。Drools里面的package实际上是一组规则的集合。包名你可以任意取,因为这里的包名仅仅针对这些规则文件有效。

接下来需要注意的就是import PermissinCheck与Role对象。这两句告诉规则引擎后面需要用到这两个对象。

最后就轮到规则检查语句了。通常一个包里面的每一条规则都会被起一个名字,这个名字经常用规则的目的来取名。这里我们的规则名为CanUserDeleteCustomers。这个规则是用来判断一个用户能否删除一条客户记录。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics