您的位置:首页 > 其它

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

2009-09-14 17:28 232 查看

15.6. 授权

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

15.6.1. 核心概念

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

15.6.1.1. 什么是角色?

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

15.6.1.2. 什么是权限?

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

15.6.2. 保护组件

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

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

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

15.6.2.1. @Restrict注释

使用
@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:hasRole
s: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上下文中查找,并传递给
Identity
hasPermission()
方法,在本例中它将确定用户是否有必须的修改指定
Account
对象的权限。

15.6.2.2. 内联约束

有时它也可以在声明在代码中来执行安全检查,而不使用
@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");

15.6.3. 用户界面中的安全

作为一个优良设计的用户界面的指标之一就是用户不会看见它没有权限使用的选项。基于以上的用户的特权,使用非常一致的组件安全性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>

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: