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");
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>
4. 保护页面
页面安全需要应用程序使用一个pages.xml文件,而且它也是非常容易配置的。仅仅是简单在你需要保护的page元素之内包含一个<restrict/>元素即可。如果restrict元素没有显式的指定一个限制,那么当通过non-faces(GET)请求访问页面时,将检查隐含的权限/viewId.xhtml:render,并且任何源于页面的JSF postback(表单提交)都需要权限/viewId.xhtml:restore。否则,指定的限制将被评定为一个标准的安全表达式,这里有两个例子:
<page view-id="/settings.xhtml">
<restrict/>
</page>
这个页面对于non-faces请求隐含一个权限许可:/settings.xhtml:render,对于faces请求隐含一个权限许可:/settings.xhtml:restore。
<page view-id="/reports.xhtml">
<restrict>#{s:hasRole('admin')}</restrict>
</page>
访问这个页面的faces和non-faces请求都需要用户是admin角色的成员之一。