@Restrict注解
Seam组件可以通过使用@Restrict
来实现方法级别或者类级别的安全控制。如果一个方法和这个方法所在类同时使用了@Restrict
注解,那么方法级别的安全限制优先级更高(意味着类级别的限制不起作用)。如果在方法上验证失败,那么与执行Identity.checkRestriction()方法一样抛出一个异常(参考相关的文档)。把
@Restrict加载一个组件类上,相当于将这个约束加在了这个类的所有方法上。
一个空的@Restrict约束默认使用
componentName:methodName作为约束。例如以下这段代码:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->@Name("account")
public class AccountAction {
@Restrict public void delete() {
...
}
}
在这个例子中,默认调用delete()方法需要
account:delete权限。效果与
@Restrict("#{s:hasPermission('account','delete')}")相等。
再来看下面这段代码:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->@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表达式,分别对应Identity类里面的方法。
这个方法能够用在所有EL表达式中,并且会用在所有安全验证相关的部分。
作为一个EL表达式,@Restrict注解的值可以关联到任何一个Seam上下文中存在的对象上。这在对某个对象实例进行权限验证的时候非常有用。
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->@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. 内部约束(Inline restrictions)
有的时候你可能会需要在某个方法的代码内部检查权限,这样就无法使用@Restrict
注解。这种情况下,你就需要用到Identity.checkRestriction()方法来执行一个与安全有关的表达式,例如:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public void deleteCustomer() {
Identity.instance().checkRestriction("#{s:hasPermission(selectedCustomer,'delete')}");
}
如果表达式未返回true则:用户没有登录——抛出NotLoggedInException异常,用户已经登录——抛出AuthorizationException异常。
同样的,你也可以在任何Java代码中使用hasRole()和hasPersmission()方法。
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->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. 程序界面中的安全控制(Security in the user interface)
一个良好的用户界面设计需要符合一个特征,用户应该只看见他所能操作的部分,而用户没有权限看见或者没有权限进行操作的按钮链接等,不应该显示出来。Seam提供了两种根据权限控制界面显示内容的方法:1)根据权限判断页面是否显示,2)根据权限判断界面中的某个控件是否显示。这两种控制都使用EL表达式来判断。
我们来看几个权限控制的例子。
首先,一个登录表单需要只有当用户没有登录的时候才能看见。如果用户已经登录,那么就不需要显示登录表单。这个功能可以使用identity.isLoggedIn()属性来判断,在页面上,我们可以写成这样:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><h:form class="loginForm" rendered="#{not identity.loggedIn}">
这种控制方式非常直观,看见代码的字面意思就应该能明白。下面,我们假设页面上有个显示所有报表的链接,这个链接只有当用户拥有manager角色的时候才能看见。我们在页面上可以这么写:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><h:outputLink action="#{reports.listManagerReports}" rendered="#{s:hasRole('manager')}">
Manager Reports
h:outputLink>
这段代码也很直观。如果用户没有manager角色,那么这个链接就不会显示。通常rendered属性可以直接卸载具体的控件内部,但是根据实际情况,也可以将它写在某个父标签上,例如
或。
现在,我们来看一个复杂点的例子。假设页面上有一个h:dataTable,用于显示一个记录列表。表格的最后一列用来显示对当前记录的操作链接,这个链接需要根据用户拥有的权限来判断是否显示。s:hasPermission表达式允许我们将当前行的记录作为参数传入权限判断函数,并根据传入的对象以及当前登录的用户来判断是否显示。下面就是这个表格的代码:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><h:dataTable value="#{clients}" var="cl">
<h:column>
<f:facet name="header">Namef:facet>
#{cl.name}
h:column>
<h:column>
<f:facet name="header">Cityf:facet>
#{cl.city}
h:column>
<h:column>
<f:facet name="header">Actionf: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>
15.6.4. 页面安全控制(Securing pages)
页面安全控制需要程序里面有pages.xml文件,不过配置代码非常简单。只需要在page标签内部添加一个对象就能够实现安全控制。
如果restrict对象没有任何属性或者子对象,那么默认情况下,来自non-faces (GET)的请求会需要权限
/viewId.xhtml:render,
JSF postback(来自表单提交方式)的请求会需要权限/viewId.xhtml:restore
。此外,如果想要指定约束规则,那么只要写出标准的安全验证表达式即可。下面是几个例子:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><page view-id="/settings.xhtml">
<restrict/>
page>
<page view-id="/reports.xhtml">
<restrict>#{s:hasRole('admin')}restrict>
page>
15.6.5. 实体安全控制(Securing Entities)
Seam安全模块同样允许将实体的添加、修改、删除操作用安全规则来控制。如果想要将对实体的所有操作用Seam安全模块来控制,那么只要在实体类上添加一个@Restrict
注解:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->@Entity
@Name("customer")
@Restrict
public class Customer {
...
}
如果@Restrict注解内部没有写任何权限判断表达式,那么默认的权限为
entityName:action,这里的
entityName为Seam组件名称(如果没有使用@Name注解来指定实体的Seam组件名称,那么也可以使用fully-qualified类名称来代替)。冒号后的操作有四种,分别是:read、insert、update、delete。
也可以单独指定某个生命周期操作,在@Restrict注解之外添加相应的注解到对应生命周期的方法上即可。共有以下四种注解:
下面这个例子介绍了如果给所有insert操作添加安全检查。请注意,这个方法并不需要做任何事情,唯一需要注意的就是,这个方法是如何被声明的:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->@PrePersist @Restrict
public void prePersist() {}
你也可以在/META-INF/orm.xml
文件中定义:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><!--sp-->xml version="1.0" encoding="UTF-8"?>
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<entity class="Customer">
<pre-persist method-name="prePersist" />
entity>
entity-mappings>
当然,你仍然需要使用@Restrict
来注解Customer对象中的prePersist()方法。
下面这个例子介绍了使用规则判断当前用户是否有权限添加一篇新的MemberBlog记录(来自seamspace示例)。The entity for which the security check is being made is automatically inserted into the working memory (in this case MemberBlog
):
分享到:
相关推荐
1. **Seam注解** - `@Name`: 这是Seam的核心注解,用于为组件定义一个唯一的名字。这个名字可以在JSF视图、表达式语言(EL)或者Seam的事件系统中引用。 - `@In`: 用于注入依赖。这相当于Spring框架中的@...
### jboss-seam 注解详解 #### @Name 在JBoss Seam框架中,`@Name`注解主要用于定义一个Seam组件。为了确保组件能够被正确识别与使用,每个Seam组件都必须拥有一个唯一的名称标识,即通过`@Name`来指定。例如: `...
### JBoss Seam 注解详解 #### 一、`@Name`与`@Scope` - **`@Name`**: 此注解用于标识一个类作为Seam组件,并为其定义一个名称,例如`@Name("componentName")`。这是所有Seam组件的必备注解。 - **`@Scope`**: ...
此外,还可以使用Seam的`@Restrict`注解进行更细粒度的控制。 3. **数据库设计**:为了实现基于数据库的权限管理,我们需要设计一个包含用户、角色和权限关系的数据库模型。通常,会有一个`User`表存储用户信息,一...
- **作用**:该注解用于定义一个Seam组件的名称。所有Seam组件都必须包含这个注解。 - **语法**: ```java @Name("componentName") ``` - **示例**: ```java @Name("userComponent") public class ...
它通过Seam组件的@SessionScoped注解实现,确保组件在整个用户会话期间保持一致的状态。此外,Seam 还提供了一种方法来处理会话超时和并发会话控制。 3. **组件(Component)机制**:Seam 的核心是组件系统,它允许...
Seam鼓励使用Java 5的注解特性来配置应用,这种方式可以减少XML配置文件的数量,提高开发效率。 ##### 7. 增强的表达式语言 Seam提供了对标准EL(Expression Language)的扩展,称为JBoss EL。这种扩展允许在...
通过使用 Seam的注解驱动编程,如`@Name`和`@In`,可以轻松地注入依赖,使得代码更加简洁和可读。 Seam还包含了强大的事件模型,允许组件之间通过发布和监听事件来通信。例如,一个组件可以通过`EventContext`发布...
Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................
通过注解,你可以告诉Seam何时、何地以及如何创建和管理你的组件。例如,`@Named`注解用于标识一个bean,`@Inject`用于注入依赖,`@ManagedBean`和`@ViewScoped`注解分别定义了bean的管理方式和作用域。 在Seam框架...
Seam和Hibernate是两个在Java开发中非常重要的框架。Seam是一个全面的、集成的Java EE框架,主要用于简化企业级应用的开发,而Hibernate则是一个强大的对象关系映射(ORM)框架,它允许开发者用Java对象来操作数据库...
**JBoss Seam 学习资源概述** JBoss Seam 是一个开源的应用程序框架,它整合了JavaServer Faces (JSF)、Enterprise JavaBeans (EJB)、Java Persistence API (JPA) 和其他Java EE技术,旨在简化开发过程,提高开发...
通常,这些Java类会继承自Seam的`ConversationScoped`或`RequestScoped`注解,以确保数据在适当的范围内有效。例如,一个名为`CountryManager.java`的类可能包含了所有国家的列表,而另一个名为`ProvinceManager....
Seam的出现就是为了消除这种隔阂,提供了一种统一的、基于注解的编程模型。 Seam的核心特性之一是整合EJB 3.0和JSF,使得业务逻辑和Web界面之间的交互更为顺畅。在传统的Java EE 5.0应用中,开发者需要创建额外的...
**Seam Carving 技术详解** Seam Carving,又称图像拉链,是一种基于能量最小化的图像调整方法,主要用于图像大小的动态调整,而不仅仅是简单的等比例缩放。它能够在保持图像主要结构不变的情况下,根据需要增加或...
"为Seam做好准备"这个标题暗示我们即将探讨的是关于Seam框架的入门与准备工作。Seam是一个Java EE集成框架,它将JavaServer Faces(JSF)、Java Persistence API(JPA)、Enterprise JavaBeans(EJB)3.0以及其他...
**JBoss Seam组件中文手册** **一、Seam框架概述** Seam是一个开源的企业级Java框架,由JBoss公司开发,旨在简化Java EE应用程序的开发。它将多种技术如JavaServer Faces (JSF),Java Persistence API (JPA),EJB 3...
- **定义组件作用域**: 可以通过注解等方式指定组件的作用域,如会话范围、请求范围等。 - **组件多重角色**: 单个组件可以拥有多个角色,例如同时作为Service和EJB使用。 #### 四、Seam组件配置 ##### 配置方式 -...