构件运行支撑平台反射体系的安全框架设计与实现*白佳,黄罡,刘钊,刘天成,郑子瞻,梅宏(北京大学信息科学技术学院软件研究所,北京100871)摘要:反射式软件中间件改变了传统中间件纯粹的“黑盒复用”方式,以观测和控制基于中间件的软件系统的运行状态和行为。作为主流的中间件产品,构件运行支撑平台有必要引入反射以适应动态开放的Internet环境。但是,在带来更大开放性的同时,反射也给构件运行支撑平台带来安全隐患。为此,针对反射体系的特点,本文逐层分析其中潜在的安全隐患,制定了一种特定于反射体系的安全框架,实现了四层安全访问控制机制。该安全框架在反射式J2EE应用服务器PKUAS中得到实现,并通过性能测试考察了安全框架对反射系统运行时刻性能的影响。关键词:反射式中间件,构件运行支撑平台,安全,J2EE1.引言Internet环境的开放、动态和多变的特性,要求运行其上的软件系统具有开放的适应性[7]。作为Internet环境下的主流基础设施,软件中间件因其传统的“黑盒复用”思想,屏蔽了底层运行环境及中间件自身的变化,难以实现开放的适应性。目前,解决这一难题的主流途径是将反射性引入中间件的构造、使用与管理,形成了中间件的研究热点之一——反射式中间件[1]。反射式中间件是一种通过与自身状态和行为具有因果关联的系统自述来描述、推理和操纵自身的中间件,而且,描述、推理和操纵自身的方式与中间件描述、推理和操纵其问题域的方式类似[5]。反射式中间件通过引入反射性来辅助开发适应性强的应用系统,它的引入增强了对中间件平台的内部状态和行为的观测和调整能力,提高了中间件平台的易用性。如图1所示,一个反射系统具有两个组成部分:一部分对系统的问题域建模并对其进行推理和操纵,以解决问题;另一部分对系统自身建模并对其进行推理和操纵,使系统适应某些变化。而且,两个部分采用同样的实现基理。从实现角度看,前一部分组成基层实体,后一部分组成元层实体,基层实体与元层实体之间具有因果关联(causalconnection),即,基层实体状态或行为的任何变化均立即导致相应元层实体的变化,反之亦然[4]。图1反射系统示意图由上图可以看到,反射体系提供了一种自身建模的机制,通过元层实体与基层实体的反射关系,在传统的“封闭式”黑盒体系上打开了若干窗口,开放系统的内部细节,大大提升了系统的开放程度。但是,∗本文得到国家重点基础研究发展规划项目计划(973计划,编号2002CB312003)、国家自然科学基金资助项目(编号60125206、60233010)、国家高技术研究发展计划(863计划,编号2001AA113060)、教育部科学技术研究重大项目(编号0214)资助。主要作者简介:白佳,男,硕士生,主要研究领域为软件构件和分布计算技术。黄罡,男,博士,讲师,主要研究领域为软件工程、软件构件和分布计算技术。通讯作者:黄罡,huanggang@sei.pku.edu.cn。开放和安全往往是矛盾的,在越开放的应用系统中,人们不得不越重视安全问题。反射式中间件允许用户观测和调整系统的状态和行为,这意味着不仅可以通过非正常渠道调用业务功能,还能通过恶意代码来修改系统使得业务用户在不知不觉中受损。设想在某应用中嵌入恶意代码,该代码试图通过元层实体操作并替换系统某基层实体,以达到破坏的目的。除非仔细研读每一个将要部署的应用的源码,否则无法确定一个应用是否存有恶意。然而,让应用服务器管理人员通读所有应用的源码并不现实。早在1990年召开的第一届反射体系国际研讨会上就已经达成共识[3]:“反射引入了一种新的安全威胁,如果不进行合理控制,将带来严重后果。”但是,直至今日,人们的关注点仍然集中在反射体系本身,而反射体系的安全考虑得较少。Oliva等人扩展了Java语言的反射[6],修改JVM以支持在Java对象创建时为其分配唯一的组装器,进而由该组装器建立元层对象与Java对象之间的因果关联。Caromel等人[2]则利用Java语言的安全管理器控制元层实体对基层实体的访问。但是,这两种安全机制都没有考虑元层对象之间的访问控制以及用户程序访问整个反射体系的安全问题,而且,使用Java安全管理器将会对性能带来较大影响。以反射式J2EE应用服务器PKUAS[8]为实验平台,本文深入全面地分析了反射体系存在的安全隐患,制定了相应的安全访问控制策略,通过集成现有的Java和J2EE安全技术,形成一种完备的反射体系安全框架,旨在解决如何在保留反射式中间件系统开放性、适应性等优点的同时,使反射式中间件系统可以像传统中间件系统那样时刻处于安全的状态,并给系统带来较小的性能损耗。值得一提的是,现有中间件的安全体系并不是绝对安全的,本文只尝试将反射式中间件的安全提升到与传统中间件相当的级别,以确保反射体系的实用性,超越现有中间件安全级别并不是本文的研究范围。文章余下部分组织如下:第二章概述反射体系安全框架;第三章介绍该安全框架在PKUAS中的实现及其性能影响;昀后总结全文并展望下一步的工作。2.方法概述不同于普通的J2EE应用服务器,反射式应用服务器由于其开放性带来了新的安全隐患。以PKUAS为例,在一次实际的访问中,客户首先访问反射系统对外提供的接口MEJB,该接口将请求转发给相应的元层实体,该元层实体进而访问基层实体的信息,并返回给客户。由于反射为系统增添了元层以及反射访问接口,因此和元层实体及反射访问接口相关的任何访问,都需要加以控制才能达到预期目标。在上述过程中,有四个层次的安全问题与此相关:客户对MEJB的访问权限及MEJB对指定元层实体的访问,元层实体之间的访问,元层实体对基层实体的访问,以及Java类对本地资源的访问,如图2所示:图2PKUAS反射体系安全层次¾客户访问控制:PKUAS定义了用户访问反射系统的接口MEJB,它是一个普通的无态会话EJB,作为一个系统级应用部署在PKUAS中。反射体系的用户只能通过MEJB访问反射体系,因此,首先必须在这一层进行控制。¾元层实体之间的访问控制:元层实体之间的相互访问也可能给系统带来破坏。如果中间件增加了新的服务或容器类型,需要提供相应的元层实体。这意味着系统中的元层实体可能来自不同的厂商,因此,必须在元层实体之间进行访问控制。¾元层实体访问基层实体的安全控制:为了防止元层实体对基层实体的恶意操作或误操作,一方面,需要禁止一个元层实体绕过另一个元层实体而直接反射后者的基层实体。另一方面,需要考虑元层实体对自身直接反射的基层实体的访问权限。¾本地资源访问控制:需要控制Java对象对本地资源的使用,如,禁止创建线程或控制线程状态,禁止建立网络连接等。3.实现和性能评测PKUAS是一个反射式构件运行支撑平台。对于上面提出的四个层次的安全隐患,下面将依次给出在PKUAS中的解决方案及其实现。昀后,通过反射系统的性能测试,评估了安全框架对系统整体性能的影响。3.1PKUAS概述PKUAS(PekingUniversityApplicationServer)是北京大学软件研究所自主研发、遵循EJB2.0规范的反射式构件运行支撑平台。PKUAS提供了反射机制,并控制反射的内容、时机、及其正确性。通过抽取一组基本功能形成一个微内核,PKUAS将平台内部的其它功能封装在各个相对独立的构件内,允许用户根据领域特征定制与扩展这些系统构件,该微内核被实现为JMXMBeanServer。利用微内核的管理机制,PKUAS方便地引入元层实体,同时做到了在不改变构件化平台结构的情况下形成元层实体与基层实体的和谐共处[5][8][9]。3.2PKUAS反射体系安全框架的实现针对上面提出的问题,PKUAS着重于在四个层次解决反射带来的安全问题。整体设计框架如下图所示:图3PKUAS反射体系安全框架从上图中可以看出一次反射请求在PKUAS内部的传递及处理方式。客户请求首先发送给PKUAS反射体系对外的接口MEJB,此时直接利用J2EE安全访问控制机制以及在MEJB内部的Controller类来控制客户访问。访问被许可后发送给相应元层实体,该元层实体根据反射访问其对应的基层实体或通过ReflectiveMBeanServer类访问其它元层实体,进而访问其基层实体。下面进行详细分析并给出解决方案。3.2.1客户访问控制客户访问可以通过PKUAS的安全截取器进行控制。但由于MEJB的方法粒度较粗,安全截取器只能对MEJB的某个方法(如getAttribute)进行访问控制,而不能针对具体的元层实体提供不同的访问权限,因此该方法并不完善。更加合理的方式是在MEJB的业务逻辑中加入控制机制,使得MEJB可以为不同的元层实体提供不同级别的访问控制。如可以针对某一个元层实体指定是否可以对它进行查询属性的操作。为达到该粒度上的控制,在MEJB中嵌入了一个Controller类,该类实现了类似于安全截取器的功能,在MEJB接收到客户请求后,该类截获请求,然后根据请求内容,查询配置文件Reflective.conf,以判断是否可以访问。根据Reflective.conf的描述,Controller决定是否把请求转发给相应的元层实体的方法并返回;或者抛出访问异常。下面给出Reflective.conf的一个例子,说明如何定义一个具体MetaEntity方法级别上的访问控制。CONFIGmethod-permissionATTRIBUTENAME=role-nameVALUE=admin/ATTRIBUTENAME=bean-nameVALUE=AppName.EntityTest/ATTRIBUTENAME=method-nameVALUE=getAttribute//method-permission/CONFIG这里Reflective.conf制定了三个必要元素:角色,MetaEntity名和方法名,只有在Reflective.conf中定义过的访问,才可以通过检查,否则都会抛出访问异常。3.2.2元层实体之间的访问控制JMX1.2规范增加了MBean之间的访问控制。基于Java的安全管理器,MBeanServer可以对MBeanServer提供的方法以及MBean定义的方法进行访问控制。但是,Java安全管理器的开启将使Java应用的性能至少下降13%~14%[2],因此,本文通过在MBeanServer外包裹一层ReflectiveMBeanServer类来实现访问控制,以替代JMX缺省的安全访问控制机制。PKUAS的类装载机制决定了一个元层实体不能直接访问另一个元层实体,而需要通过JMX提供的MBeanServer进行调用。通过在MBeanServer外包裹一层ReflectiveMBeanServer,就可以在请求转发至MBeanServer前进行权限判断。当元层实体访问另一个元层实体时,首先将请求以及自身角色信息传给ReflectiveMBeanServer,ReflectiveMBeanServer中内嵌的Controller类读取配置文件Reflective.conf判断该角色是否有权限进行本次访问,根据判断的结果将请求转发给JMX的MBeanServer或者抛出访问异常。值得一提的是,客户访问控制和元层实体之间的访问控制两部分复用同一个权限配置文件与Controller类,简化了反射体系安全框架的使用。3.2.3元层实体访问基层实体的安全控制由于元层实体往往由基层实体提供者开发,因而不需要考虑直接反射基层实体的元层实体是否执行恶意操作。但是,如果一个元层实体能够绕过另一个元层实体而直接访问那个元层实体反射的基层实体,安全依然无法得到保证。PKUAS的类装载机制很好的解决了这个问题,它保证只有服务、容器系统或容器的元层实体才能使用其基层实体的类装载器[8],而一个对象无法直接调用被其它类装载器装载的对象,因此,只有通过MBeanServer,一个元层实体才能访问另一个元层实体,进而反射其基层实体。这样保证了元层实体对基层实体的访问安全。3.2.4本地资源访问