`
stenlylee
  • 浏览: 261561 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Seam中基于ACL的权限控制(1)

阅读更多

Seam框架已经能够解决大多数web程序开发中会遇到的问题。通过提供一系列基于“最佳实践”总结出的统一模型,开发人员的web程序的开发工作变得非常轻松。程序员在开发具体的相关业务逻辑的时候,就不会再郁闷了,因为大多数功能在Seam中都有对应的模块来实现。例如,Seam生成PDF、发送email、实现国际化等,都非常方便。同时,Seam还集成了许多第三方框架,例如Drools、jBPM等,这些框架写作能够实现非常复杂的业务逻辑以及跨度时间很长的流程操作。其他还支持自动生成验证码、wiki风格的标记语言和一大堆AJAX功能。

 

其中最重要的企业特性之一,就是Seam的权限控制部分。Seam包含一个非常健全的安全认证API,通过这个API,一个典型的程序中需要用到的组件和视图安全认证都能够实现。Seam通过用户角色以及基于规则的权限控制来实现安全控制。最近的版本中(2.1.0GA),Seam重写了安全引擎,提供了大量新的相关功能来保障敏感数据的安全。本文就来看看其中一个新的特性——权限的持久化,着重于介绍ACL或者说是基于实例的安全机制是如何在对象级别保障你程序的安全的。

 

开始之前,让我们先来看看基于规则的与基于ACL的安全控制有什么不同。基于规则的安全控制擅长于将一堆权限授予某个对象。例如下面这段规则代码(来自于Seam的示例项目):

 

  rule DeleteImage
    no-loop
    activation-group "permissions"
  when
    acct: MemberAccount()
    image: MemberImage(mbr : member -> (mbr.memberId.equals(acct.member.memberId)))
    check: PermissionCheck(target == image, action == "delete", granted == false)
  then
    check.grant();
  end

 

这段规则做了这么一个限制:让用户有权限删除他之前上传的图片。其中最重要的部分限制了,只有图片的所有者才能删除图片。在这个例子中,该权限加在所有图片上,并且在图片和其所有者之间拥有一种连接关系。通过这条关系,安全规则能够决定当前用户即为该图片的所有者,并且将相应的权限授予其执行操作。不过,如果在需要检查的对象的权限如果与当前用户没有关联呢?(在这里,用户就是只principal)这样就需要ACL了。

 

ACL(访问控制表)记录了某个指定的对象与某个权限之间的一一对应关系。每个记录都拥有一个接受者(被授予权限的用户principal)和一个操作。如果你使用过unix系列的操作系统,那么你就会对ACL非常熟悉了,unix操作系统有一个表格用来记录某个用户对某个文件的修改、删除或执行权限。当然Windows也有这样的机制,不过Windows并没有表现出他是这样控制的。Seam中的ACL也是一样的,唯一不同的就是,Seam中ACL记录的对象是实体的实例,而不是文件。通常情况下,这个对象为实体,不过我们将会看见,它可以应用到所有类型的对象上。

 

当我们为对象指定权限的时候,我们需要先来做点准备工作。其中最重要的,就是为我们的权限准备一个存储方式。Seam提供了一个PermissionStore接口,这个接口中定义了各种基于ACL的对象权限管理方法。理论上,权限的存储方式可以为所有可能的方式,例如文件、LDAP等等。不过通常,我们都用关系数据库来存储。所以Seam提供了一个PermissionStore的实现——JpaPermissionStore,它使用JPA来管理存储在数据库中的权限。要想使用JpaPermissionStore,我们需要做两件事情,第一是写一个Entity,来映射管理数据库中的权限记录,第二是在component.xml中添加相应的配置文件。

 

 

Seam提供一组专用于权限的注解,用来将Entity中的属性与数据库中的字段对应起来。下面这段代码为配置权限Entity的最简情况(为了版面简介,这里省略了所有的getter与setter):

 

@Entity
public class AccountPermission implements Serializable
{          
   @Id @GeneratedValue public Integer permissionId;
   @PermissionUser @PermissionRole public String recipient;
   @PermissionTarget public String target;
   @PermissionAction public String action;
   @PermissionDiscriminator public String discriminator;
}

 

@PermissionUser与@PermissionRole注解用来指定权限的接受者。在这里,我们用一张表来管理角色的权限与人员的权限,所以我们将这两个注解加到同一个属性上。同时,为了做到这一点,我们需要一个专门的字段来当作辩析器,指明这条权限是针对角色的还是针对用户的,我们将@PermissionDiscriminator加到另外一个属性上,就能将一个字段变为辩析器。最后,我们需要一个字段来指明权限适用的对象(@PermissionTarget)与权限的操作(@PermissionAction)。

 

下面我们需要在components.xml文件中添加相应的配置了,添加这个配置信息,目的是为了启用JpaPermissionStore:

 

<security:jpa-permission-store user-permission-class="com.acme.AccountPermission" />

 

现在我们配置也做了,Entity也写了,下面我们就可以开始分配权限了。Seam提供了一个组件,叫做PermissionManager,帮助我们完成权限管理方面的工作。PermissionManager里面的方法与PermissionStore接口里面的非常类似,实际上它也是将大多数工作递交给底层的PermissionStore实现,唯一不同的地方就是,它在执行相关操作之前,会先检查一下当前用户是否拥有该操作所对应的权限。更多相关的内容,请参考Seam的文档。然而,不是所有用户都有权管理权限的,必须要有相关的授权才可以。

 

让我们来授予用户第一个权限!假设程序里面有一个customer表,对应的Entity为Customer,你需要将不同客户的资料管理权限授予不同的销售人员。加入你需要张三去管理你最好的客户——李四(对应的客户编号为1234)。我们将客户李四资料的维护权限授予张三的代码会是下面这样:

 

PermissionManager.instance().grantPermission(new Permission(entityManager.find(Customer.class, 1234), "update", new SimplePrincipal("bob")));

 

PermissionManager的实例会调用grantPermission()方法来将新的权限生成一条记录,然后保存进数据库。这个操作会自动递交给你配置的JpaPermissionStore来执行(当然,这个操作首先会检查当前用户是否有权进行)。我们来看一下这个操作在AccountPermission产生了什么效果:

AccountPermission
=================
RECIPIENT  TARGET         ACTION  DISCRIMINATOR
-----------------------------------------------
bob        Customer:1234  update  user

 

我们可以从数据库查询结果中很显然地看到,这条权限的接受者是bob,对象是编号为1234的Customer,操作是更新,并且这条对象是授权给bob这个用户而不是某个名叫bob的角色,因为辨别器中写的是user而不是role。

 

其中target的值比较有意思,我们可以看见,这个字段的值有两个部分,冒号前面的部分是对象的名称Customer,而冒号后面为对象的ID。在Entity中,Seam可以自动生成对象的ID。

 

但是,如果我们需要记录的权限对象不是一个实体,而是其他的类,那么就需要让Seam知道如何来生成针对某个任意对象的唯一标识符。我们可以添加@Identifier到相应的类上,并且添加一个实现了IdentifierStrategy接口的类。例如:

 

@Identifier(CustomIdentifierStrategy.class)
public class MyNonEntityClassThatIWantToAssignPermissionsTo {
   public String getUniqueProperty() { return foo; }
}

 

IdentifierStrategy也非常简单,只要实现两个方法就可以了。canIdentify()在IdentifierStrategy能够为指定的类生成唯一标识符的时候返回true,getIdentifier() 则为指定的对象返回生成的唯一标识符。例如,Seam内置实现的EntityIdentifierStrategy类就是为某个Entity生成一个调用对象编号的name。

 

 

public class CustomIdentifierStrategy implements IdentifierStrategy {
  public boolean canIdentify(Class targetClass) {
    return targetClass.equals(MyNonEntityClassThatIWantToAssignPermissionsTo.class);
  }
  public String getIdentifier(Object target) {
    return ((MyNonEntityClassThatIWantToAssignPermissionsTo) object).getUniqueProperty();
  }  
}

 

还有值得一提的,你也可以为某个字符串常量指定权限。例如,权限的对象不一定非要是Entity或者某个类。PermissionManager同样也很乐意接受一个简单的字符串作为权限对象,因为有可能你需要的一个权限,仅仅是你根据需要任意指定的一个权限而已。对于一个普通的类,你就可以这么做,例如你想针对一个类创建一条权限,名叫“创建”,然后用这个权限来限制用户能否创建一个类的实例(new ClassName的方式)。不过你无法创建一个基于类的权限去作用于一个不存在的类。

 

通过上面介绍的这些,你已经可以通过Seam内置的权限管理模块来对你程序里涉及到的权限进行控制了。具体的在Seam官方文档里面有介绍。

 

下一篇文章我们将会一起来探讨,权限相关的操作是如何定义并且存储的。并且我也会介绍一下如何创建用户体验良好的权限管理界面,来简化权限管理方面的操作。

 

敬请期待

  • 大小: 4.4 KB
  • 大小: 1.7 KB
分享到:
评论
3 楼 Visa 2009-05-11  
2 楼 ltj_007 2009-03-05  
   
1 楼 wan_2004 2009-02-27  
 

相关推荐

    接上篇(seam登录时的权限验证)之“seam基于数据库的权限验证”

    在本篇讨论中,我们将深入探讨如何在Seam框架下进行基于数据库的权限验证,以此来确保用户只有在具备相应权限的情况下才能访问特定的资源。 首先,我们要理解Seam中的安全模型。Seam使用了JSF(JavaServer Faces)...

    SEAM 中文开发指南

    - **SEAM**:SEAM 是一个基于 Java EE 的企业级应用框架,它简化了复杂的应用程序开发过程,并且提供了丰富的功能来支持业务逻辑的实现。 - **版本信息**:本文档介绍了 SEAM 2.0 GA 版本的功能特性及其使用方法。 ...

    jboss seam 中文文档集合

    JFreeChart-1.0.5-Ch.chm提供了详细教程和示例,帮助开发者利用JFreeChart在Seam应用中展示数据。 **7. ANTLR** ANTLR 是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件。ANTLR中文...

    JBOSS SEAM组件中文手册

    1. **组件(Components)**: Seam的核心是组件模型,它允许开发者定义和管理应用中的对象。组件可以是简单的Java类,也可以是EJB或JSF Managed Beans。Seam自动管理组件的生命周期,包括创建、初始化、销毁等过程。 ...

    seam in action 中文 english

    1. **组件化**:Seam引入了一种强大的组件模型,使得开发人员可以轻松地创建、管理和组合应用程序组件。这些组件可以是UI元素、业务逻辑或者数据访问对象,它们通过依赖注入(Dependency Injection, DI)进行通信,...

    seam 中文文档 pdf

    seam 中文文档 pdf 格式 JSF+EJB3.0快速开发框架Seam的中文版向导。。。

    MATLAB_Seam_Carving_seamcarving_

    Seam Carving是一种基于能量的图像缩放技术,由Ariel Shamir和Shai Avidan在2007年提出。它的核心思想是找出图像中的一条或多条“能量最低”的路径(seam),沿着这些路径删除或添加像素,从而实现图像的等比例或非...

    Seam2.0GA 中文开发指南

    Seam支持拦截器机制,可以用来增强组件的行为,例如日志记录、权限检查等。 **3.2.7 组件名字** 每个Seam组件都有一个唯一的名称,用于在应用中引用该组件。 **3.2.8 定义组件范围(Defining the Component Scope...

    seam需要的jar包

    在这个“seam需要的jar包”压缩包中,包含了运行和开发Seam应用程序所需的各种库文件。 首先,Seam框架的核心依赖于JSF,这是Java EE中的一个用户界面组件框架,用于构建交互式Web应用。JSF提供了模型-视图-控制器...

    jboss seam 中文文档

    - **拦截器**:在 Seam 中,拦截器被用来增强组件的行为,如权限检查、日志记录等。 - **组件名字**:每个 Seam 组件都需要有一个唯一的名称,以便于引用和配置。 - **定义组件作用域**:通过配置文件或注解,可以...

    Seam security

    1. 安全原则:Seam Security围绕几个关键的安全原则构建,包括身份认证、身份管理和授权控制。身份认证是证明用户身份的过程,通常依赖于用户提供的秘密信息,如密码。身份管理负责处理用户的身份信息,包括用户的...

    JbossSeam中文开发指南.docx

    Jboss Seam是基于Java EE 5.0的框架,提供了一个基于组件的架构,能够帮助开发者快速构建企业级应用程序。Seam框架提供了一个统一的编程模型,能够将JSF、EJB、JPA等技术整合在一起,提供了一个强大且灵活的开发环境...

    seam 2中文手册

    seam下一代web开发框架

    (可直接运行)国外的seam carving matlab源码(包含gui)

    在MATLAB中实现Seam Carving,可以利用其强大的矩阵运算和图形用户界面(GUI)功能。 MATLAB源码中的"seamCarving_GUI.m"文件应该是整个程序的主入口,它构建了一个图形用户界面,用户可以通过这个界面加载原始图像...

    Jboss Seam中文版

    1. **在JBoss AS上运行示例**:首先需要安装配置JBoss AS服务器,然后导入Seam项目到服务器中进行部署。 2. **在Tomcat服务器上运行示例**:Tomcat作为轻量级的应用服务器,可以快速部署简单的Seam应用,便于学习和...

    为Seam做好准备

    1. **Java EE基础知识**:Seam是基于Java EE平台构建的,因此,对Servlet、JSP、JSF、JPA、EJB等基础技术的掌握是必要的。理解它们的工作原理有助于更好地利用Seam提供的功能。 2. **JavaServer Faces (JSF)**:...

    Seam框架文档简述

    Seam,全称为JBoss Seam,是一款基于Java EE 5的技术栈构建的应用框架。它通过整合JSF(JavaServer Faces)与EJB 3.0(Enterprise JavaBeans 3.0)组件,并充分利用JDK 5.0中的注解技术,为开发人员提供了构建复杂...

    Seam 2.1 安全模块框架

    3. **权限验证**:Seam 包含一个广泛适用的权限验证框架,支持基于角色的访问控制(RBAC)、持久化权限设置以及规则驱动的权限决策。这使得开发者可以根据业务逻辑创建自定义的安全策略。 4. **权限管理**:Seam ...

    jboss seam中文资料

    JBoss Seam是一个基于Java EE的应用框架,主要用于简化企业级应用的开发过程。它整合了多种技术和模式,如JSF(JavaServer Faces)、EJB 3.0、JPA(Java Persistence API)等,从而提供了一个强大的开发平台。Seam ...

    seam2.0 中文文档

    - **安全性**:描述Seam的安全特性和如何配置权限控制。 - **最佳实践和案例研究**:分享一些实际应用中的经验和技巧,以及常见问题的解决方案。 **文件名称列表解析:** - **index.html**:这是文档的主入口文件...

Global site tag (gtag.js) - Google Analytics