Seam的安全框架-授权(Authorization)(译) (一)

Seam安全API为安全访问组件、组件方法和页面提供了几种授权机制。本节将描述他们。一个需要注意的重要事项是如果你想使用任何高级特性(比如基于规则的权限),你需要在components.xml中配置它们以得到支持。(参见配置一节)。

Seam安全的建立是围绕着用户被赋予角色并且/或者权限,允许它们执行那些在没有必要的安全特权就不能执行的操作的前提下的。Seam安全API提供的每一种授权机制都建立在角色和权限这些核心概念之上,这些概念拥有一个提供多种方式保护应用资源的易扩展的框架。

角色是被赋予某些特权,可以执行一个和多个应用中的动作的用户的一个 类别。简单的角色仅仅由一个名称组成(比如"admin","user","customer"等等)。可以将角色赋予用户(或者其他的角色),也可以被用来为方便分配指定的特权而创建用户的逻辑组。


权限是一种执行一个单独的、特定的动作的特权(有时是一次性的)。一个应用只使用权限是完全可能的,然而角色在给一组用户赋予权限是提供了更高级别的便利 性。权限的结构比角色稍复杂,主要由三个方面构成:目标、动作和接受者。权限的目标是一个对象(或者一个任意名称和类),允许指定的接受者(或用户)执行 这个对象的一个特定的动作。例如,用户“Bob”有权限删除customer对象。在这个例子中,权限目标是“customer”,权限动作是 “delete”,权限的接受者是“Bob”。


本文中,权限通常以target:action这种形式表现(忽略了接受者,尽管实际上一个接受者是必须的)。

让我们以@Restrict注释来研究最简单的授权和组件安全为开端。

@Restrict与类型安全的安全注释

由于@Restrict注释支持EL表达式,使得该注释为保护组件方法提供强大并且灵活的方法,建议使用类型安全的等价物(以后描述),至少在编译期间是安全的。

使用@Restrict注释,可以在方法和类级别上保护Seam组件。如果一个方法和它声明类都使用了@Restrict注释,方法的约束将有更高的优先级(并且类约束将不起作用)。如果一个方法调用在安全检查使失败,按照Identity.checkRestriction()的约定,它将抛出一个异常(参见内联约束)。在组件类级别上的@Restrict注释等价于它每个方法都使用了这个注释。

一个空的@Restrict意味着一个默认的权限检查:componentName:methodName。如下所示:
@Name( " account " )
public   class  AccountAction {

    @Restrict 
public   void  delete() {
      
    }

}
在这个例子中,调用delete()方法时需要的隐含权限是account:delete。与@Restrict("#{s:hasPermission('account','delete')}")这样写是等价的。现在,让我们看看另外一个例子:
@Restrict @Name( " account " )
public   class  AccountAction {

    
public   void  insert() {
      
    }

    @Restrict(
" #{s:hasRole('admin')} " )
    
public   void  delete() {
      
    }

}
这次,组件类本身使用了@Restrict注释。这意味着任何没有重写@Restrict注释的方法都需要一个隐含的权限检查。在这个例子中,insert()方法需要一个account:insert权限,而delete()方法需要用户是"admin"角色的一个成员。

在继续深入前,先解释一下上面看见的#{s:hasRole()}表达式。s:hasRoles:hasPermission都是EL函数,贯穿整个安全API,这些函数能在任何EL表达式是使用。

通过一个EL表达式,@Restrict注释的值可以引用存在于Seam上下文中的任何对象。这在为一个指定的对象实例执行权限检查是非常有用的。看这个例子:
@Name( " account " )
public   class  AccountAction {

    @In Account selectedAccount;

    @Restrict(
" #{s:hasPermission(selectedAccount,'modify')} " )
    
public   void  modify() {
        selectedAccount.modify();
    }

}
在这个例子中需要说明的有趣的一点是hasPermission()函数调用了selectedAccount方法的引用。该变量值将在Seam上下文中查找,并传递给IdentityhasPermission()方法,在本例中它将确定用户是否有必须的修改指定Account对象的权限。 有时它也可以在声明在代码中来执行安全检查,而不使用@Restrict注释。在这种情况下,简单的使用Identity.checkRestriction()来评估安全表达式,就像这样:
public   void  deleteCustomer() {

    Identity.instance().checkRestriction(
" #{s:hasPermission(selectedCustomer,'delete')} " );

}
如果这个指定表达式评估后不为true,并且
  • 如果用户没有登录,将抛出NotLoggedInException异常,或者

  • 如果用户已经登录,将抛出AuthorizationException异常。

也可以在Java代码中直接调用hasRole()hasPermission()方法:
if  ( ! Identity.instance().hasRole( " admin " ))
     
throw   new  AuthorizationException( " Must be admin to perform this action " );

if  ( ! Identity.instance().hasPermission( " customer " " create " ))
     
throw   new  AuthorizationException( " You may not create new customers " );

作为一个优良设计的用户界面的指标之一就是用户不会看见它没有权限使用的选项。基于以上的用户的特权,使用非常一致的组件安全性EL表达式,Seam安全允许有条件的渲染 1)页面的区段和 2)独立的控件。

让我们看看一些界面安全的例子。首先,假设我们有一个登录表单,它只能在用户没有登录的时候被渲染。使用identity.isLoggedIn()特性,我们可以这样写:
< h:form  class ="loginForm"  rendered ="#{not identity.loggedIn}" >
如果用户没有登录,那么登录表单将被渲染-到目前为止,非常简单。现在,假设页面上有一个菜单,它包含一些只能被是“manager”角色的用户访问的动作。可以写成这样:
< h:outputLink  action ="#{reports.listManagerReports}"  rendered ="#{s:hasRole('manager')}" >
    Manager Reports
</ h:outputLink >
这也相当直截了当。如果用户不是manager角色的成员,那么这个outputlink将不会被渲染。rendered属性通常是控件本身使用,或者是一个被包围的<s:div><s:span>控件。

现在看看一些更复杂的。假设你有一个h:dataTable控件,其中的数据列表中你希望依靠用户的权限来决定是否被渲染而显示。s:hasPermission这个EL函数允许我们传递一个可以决定是否用户拥有要求的权限的对象参数。这样的被保护的dataTable可能像这样:

< h:dataTable  value ="#{clients}"  var ="cl" >
    
< h:column >
        
< f:facet  name ="header" > Name </ f:facet >
        #{cl.name}
    
</ h:column >
    
< h:column >
        
< f:facet  name ="header" > City </ f:facet >
        #{cl.city}
    
</ h:column >
    
< h:column >
        
< f:facet  name ="header" > Action </ f:facet >
        
< s:link  value ="Modify Client"  action ="#{clientAction.modify}"
                rendered
="#{s:hasPermission(cl,'modify')" />
        
< s:link  value ="Delete Client"  action ="#{clientAction.delete}"
                rendered
="#{s:hasPermission(cl,'delete')" />
    
</ h:column >
</ h:dataTable >





转载于:https://www.cnblogs.com/rgbw/archive/2009/09/14/1566499.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值