中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> Bea专区 > WebLogic Server
Java与安全性,第1部分
作者:Avinash Chugh 时间:2006-08-10 05:00 出处:bea.com.cn 责编:月夜寒箫
              摘要:Java与安全性,第1部分

  编辑注:本文节选自《WebLogic: 权威指南》一书的17章,分为2个部分。在第1部分中,作者Avinash Chugh 和Jon Mountjoy从考察Java Security Manager和WebLogic如何过滤请求开始,对WebLogic的各种安全机制进行了分析。文章还涵盖了WebLogic的身份认证和授权框架,以及它如何支持标准的J2EE安全服务。

  WebLogic提供一套功能全面的安全服务,这些服务可以从各个方面保护域及其部署。这些安全服务影响到域的所有方面:从Java Security Manager提供的最底层安全性,到连接级别的安全性,再到应用级别的安全性(可以保护所管理和部署的对象,比如EJB,web服务和JDBC池),最后到域级别的安全性(可以建立两个域之间的信任)。这些安全服务的目标是3个截然不同的用户群:可以使用服务来保护其应用程序的应用程序开发人员;需要为系统和部署配置安全性的管理员;以及可以修改和扩展WebLogic所提供的功能的安全性供应商。

  让我们从JVM层开始。在这一层,Java Security Manager使用一个安全性策略文件来限制对特定的运行时操作的访问。这确保了运行在JVM(包括WebLogic Server本身)上的程序仅可以许可方式访问受保护的资源。例如,可以配置Java Security Manager,以便让所有线程都拥有仅对于文件系统中特定目录的写权限。通过允许为资源适配器和EJB定义另外的安全策略,WebLogic增强了Security Manager,从而确保了这些组件能够只访问已定义的资源。还有一些其他的全局高级安全性权限可以应用于这些资源和应用程序代码。

  WebLogic可以从客户端过滤连接请求。连接过滤器定义了一些规则,规定了如何确定服务器是接受还是拒绝客户端连接。这些规则基于几个参数,这些参数通常包括:客户端的IP地址和端口;用于建立连接的协议;以及服务器的监听地址和端口。可以为一台服务器指定多个连接过滤器,甚至可以编写自己的连接过滤器类来实现定制的过滤逻辑。例如,通过使用连接过滤器,可以很容易地确保服务器只接受来自内部网的T3连接。SSL安全性是另一种可在套接字层上使用的机制,我们在16章中已经讲述过这种机制。SSL可以通过支持数据完整性、机密性和身份验证,保护给定的网络通信。

  WebLogic部分地支持标准的JAAS。JAAS框架是对J2SE v1.3的一种标准扩展,现在已成为J2SE v1.4平台的一部分。身份验证使服务器可以验证运行Java代码的用户的身份,不论它是applet、servlet、EJB还是应用程序。授权则使服务器能够基于用户的身份、安全权限和策略实施访问控制。WebLogic允许Java客户端使用JAAS身份验证,而且逻辑模块也是使用JAAS实现的。如果需要使用JAAS授权,就必须在WebLogic的基础架构上编写自己的模式。

  WebLogic的安全性基础架构建立在一组模块化的、可扩展的安全服务提供程序接口(security service provider interfaces ,SSPI)之上。这种架构允许插入新的安全提供程序替换旧的,并可以与用户自己的提供程序一起运行WebLogic的默认提供程序。WebLogic发行文件配备了一组安全提供程序,为SSPI提供默认实现。WebLogic的安全提供程序为J2EE应用程序实现了底层安全性框架。也就是说,标准的J2EE定义的安全机制是通过SSPI实现(和扩展)的。通常,WebLogic的安全提供程序会改进现有的安全约束。例如,标准的ejb-jar.xml部署描述符允许限定只有具有特定角色的、已通过身份验证的用户才能访问某个EJB方法。WebLogic允许改进这种约束,确保用户只在一天中的某些时段具有访问权。事实上,SSPI是一种开放的架构,可以很容易地插入来自某家安全供应商的第三方安全提供程序。另外,还可以通过实现自己的安全提供程序来构建新的安全服务。

  WebLogic默认的安全提供程序功能相当全。security realm(安全域)就是一个用户、组、角色、安全策略的逻辑分组,以及一整套安全提供程序。为服务器资源指定的安全策略可用于确定授权谁访问资源。WebLogic使用户可以保护所有的资源:单个EJB方法、web应用程序、web页面的集合、连接池、数据源或者任何受管理的对象。甚至可以保护JNDI树中的分支,从而防止未得到授权的客户端在JNDI树中查找对象。所有这些安全数据都保存在一台嵌入式LDAP服务器中。还可以配置WebLogic来使用外部的LDAP库,比如Open LDAP,Active Directory,或Novell NDS。这些外部库只能用于身份验证,而不能用于授权。

  最后,WebLogic允许在两个域之间建立一种信任机制。这确保了一个域中已通过身份验证的用户可以访问另一个域中的资源。

  本章分析了所有这些安全机制。尽管它们彼此大相迥异,但是它们互相补充得非常好。我们从考察Java Security Manager和WebLogic如何过滤连接请求开始,然后分析WebLogic的身份验证和授权框架,并了解它如何支持标准的J2EE安全服务。我们还切换使用了安全域中可用的各种安全提供程序以及它们的默认实现。最后,我们将考察如何使用JAAS进行身份验证,并举一个Authentication 和Identity Assertion提供程序的例子。

Java Security Manager

  在JVM层上,WebLogic可以使用标准的Java Security Manager来防止不受信任的代码执行有害的动作。可以使用安全策略文件来配置JVM,以便让运行在JVM上的所有线程都能够受限制地访问敏感的运行时操作。安全策略文件封装了一组权限,这些权限将授予给当前的JVM实例中加载的所有类(或者取消)。可以定义一整套安全权限来控制对特定资源的访问——例如,对于文件系统上某个文件夹的“写(write)”访问权限,对于特定主机和特定范围的端口的“连接(connect)”访问权限,对于环境变量的“读(read)”访问权限,对于当前类加载器的“获取(get)”访问权限,等等。要获得更多关于Security Manager和安全策略文件的信息,请参考JDK说明文档。

  Java的Security Manager确保运行在WebLogic中的任意代码都仅可以许可的方式访问这些重要资源。这种低级的访问控制对于第三方不受信任代码可能很有用。Java Security Manager还可以与J2EE部署设置交互。例如,可以使用标准的ra.xml部署描述符来定义应用于资源适配器的安全权限。WebLogic也为web应用程序和EJB提供类似的访问控制。

  注意,WebLogic需要有一个可用的策略文件才可以运行。startWebLogic脚本用于加载默认位于WL_HOME/server/lib/weblogic. Policy下的策略文件。

配置Security Manager

  为了使用Java Security Manager,需要在启动WebLogic Server时从命令行提供两个选项:

  • 必须使用–Djava.security.manager选项,以确保安装了默认的安全管理器而且JVM通过了策略检查。
  • 必须使用–Djava.security.policy选项,以指定安全策略文件的位置。

  默认情况下,JVM使用定义在java.security和java.policy文件(位于JAVA_HOME/jre/lib/security文件夹中)中的安全策略。下面是使用定制的安全策略文件启动WebLogic Server的语法:

java –Djava.security.manager –Djava.security.policy==c:oreilly.policy

... weblogic.Server

  WebLogic创建的默认启动脚本引用了位于WL_HOME/server/lib/weblogic.policy下的示例安全策略文件。注意,指定java.security.policy参数时,我们使用了==(双等号)。这使得Security Manager使用c:oreilly.policy作为它惟一的策略源。如果我们只使用一个等号,该策略文件就会与JDK安装所提供的默认安全策略文件一起使用。

  通常,JVM将使用安全策略文件对运行在WebLogic中的任意代码实施访问控制。这条规则惟一的例外是在WebLogic Server启动时。当服务器启动时,WebLogic部分地禁用了Java Security Manager,并使用一个禁用checkRead()方法的变体来替换它。虽然这种方法改进了启动顺序的性能,但是它也会降低JVM在启动期间的安全性。另外,它意味着WebLogic的启动类将使用这个修改过的安全管理器运行。需要确保这些类不会导致破坏安全性。

  注:因为策略文件决定了运行在WebLogic的JVM中的所有类的访问权限,所以建议只有管理员才能读写安全策略文件。不应该允许其他用户访问策略文件。

全局安全策略

  WebLogic允许为EJB、资源适配器和weblogic.policy文件中的web应用程序定义安全策略。表17-1列出了为这些组件类型定义默认权限所用的代码基址。

表17-1. 应用于J2EE组件的访问权限的默认代码基址

应用程序类型

代码基础

EJB

文件:/weblogic/application/defaults/EJB

资源适配器

文件:/weblogic/application/defaults/Connector

Servlet

文件:/weblogic/application/defaults/Web

  可以使用这些代码基础对特定的J2EE组件类型授予特殊的权限。注意,在这些代码基址下定义的任何安全策略都可以应用于所有的EJB、资源适配器和部署到特定的服务器实例的web应用程序。

特定于应用程序的安全策略

  还可以定义特定于某个EJB组件或资源适配器的安全策略,从而确保只以特定的组件为目标。为此,必须修改它们的部署描述符,而不是策略文件本身。资源适配器支持这种作为J2EE标准一部分的机制,只需修改标准的ra.xml描述符文件。对于EJB,需要修改weblogic-ejb-jar.xml描述符文件。两种情况中,都是securitypermission元素允许用户定义另外的安全策略。

  让我们看一看如何为EJB指定权限。weblogic-ejb-jar.xml描述符中的security-permission元素指定了应用于打包在EJB JAR中的所有EJB的安全权限。下面的例子授予服务器文件系统中的一个临时目录对EJB的读和写的访问权限:

<weblogic-enterprise-bean>
<!-- webLogic enterprise bean statements go here -->
</weblogic-enterprise-bean>
<security-role-assignment>
<!-- the optional security role assignments go here -->
</security-role-assignment>
<security-permission>
<description>
grant permission to special folder
</description>
<security-permission-spec>
grant {
permission java.io.FilePermission
"f:
tmp
-", "read,write";
}
</security-permission-spec>
<security-permission>

  注意security-permission-spec元素如何使用相同的语法为安全策略文件定义授权权限。这种语法惟一的限制就是不能使用代码基址或signedBy子句。

跟踪 Security Manager

  BEA 提供了一个Recording Security Manager,用于跟踪任何由Java Security Manager引起的权限问题。安装时,该工具会检测并记录在运行时出现的任何访问控制异常。这样,就可以轻松地找出出现在访问控制中的问题,稍后再重新配置安全策略,以移除这些错误。该工具并未与WebLogic Server一起发布。但是,可以从BEA的dev2dev web站点(http://www.dev2dev.bea.com)下载它。

连接过滤

  在连接层次上,WebLogic提供两种安全性功能:过滤和SSL。16章详细讲述了SSL。这里我们将讲述连接过滤。连接过滤器允许服务器基于某种条件拒绝有害的连接。例如,连接过滤器将允许将WebLogic配置为仅许可来自内部网的T3和IIOP连接,而拒绝来自内部网之外的连接请求。所以,连接过滤提供的是网络层的访问控制。

  WebLogic带有一个默认的连接过滤器,用于分析定义在Administration Console(管理控制台)中的一条或多条连接过滤器规则。另外,还可以创建自己的定制连接过滤器,用于评估服务器所接受的传入连接的基本原则。定制的连接过滤器是一个实现WebLogic的ConnectionFilter接口的Java类。该接口十分简单——该Java类要实现accept()方法,该方法只是抛出FilterException异常以表明传入的连接请求不应该被允许通过。下面给出了一个连接过滤器的例子,它只接受来自IP地址与10.*.*.* 匹配的主机的T3连接:

mport weblogic.security.net.*;
public class MyConnectionFilter implements ConnectionFilter {
public void accept(ConnectionEvent evt) throws FilterException {
if ( evt.getProtocol( ).equals("t3") ) {
byte [] addr = evt.getRemoteAddress( ).getAddress( );
if ( !(addr[0]==10))
throw new FilterException( );
}
};
}

  只要违反过滤器规则,该过滤器就抛出一个FilterException异常。如果到方法结束时还没有抛出任何异常,连接就被允许通过。该方法只接收一个参数,即一个ConnectionEvent对象,它封装了有关连接请求的重要信息。通常,可以使用这些信息执行过滤器的接受规则。ConnectionEvent类提供多个方法来访问这些信息:

getProtocol()
获得一个表示用于建立连接的协议的字符串值。

getRemoteAddress()
获得一个表示客户端地址的 java.net.InetAddress 对象。

getRemotePort()
返回用于建立连接的客户端端口号。

getLocalAddress()
获得一个表示服务器的监听地址的java.net.InetAddress 对象。

getLocalPort()
获得连接指向的服务器端口号。

  编译过滤器类之后,需要安装它。首先,需要确保从服务器的类路径可以定位该类。然后,使用Administration Console,展开指示域的最顶层节点,并选择View Domain-Wide Security Settings选项。Configuration/Filter选项卡包含连接过滤器设置。WebLogic 7.0用户从左侧窗格展开域节点,然后选择Security/Filter选项卡。

  在Connection Filter设置中输入连接过滤器名称。您还将看到Connection Filter Rules设置。如果您的过滤器类还实现了可选的ConnectionFilterRulesListener接口,请使用这个选项。在这种情况下,连接过滤器将能够接收和处理定义在Administration Console中的过滤器规则。

默认连接过滤器

  WebLogic中预配置了一个非常有用的连接过滤器,可以处理大量使用Administration Console在Connection Filter Rules设置中定义的过滤器规则。连接过滤器将尝试把传入的连接与所有规则进行匹配,从清单中的第一条规则开始。如果找到了匹配的规则,将根据规则的动作允许(或禁止)连接。如果没有找到匹配的规则,传入的连接就被许可。

  可以指定多条规则;每条规则都应该是单独的一行。下面给出了连接过滤器的语法:

target localAddress localPort action protocolList

  下面给出了连接过滤器规则的各个参数的定义:

  • target参数指定规则必须审查的client host。稍后我们将讨论它的语法。
  • localAddress参数指出客户端要连接的服务器的主机地址。如果指定为星号(*),这将对应所有的本地IP地址。
  • localPort参数指示客户端要连接的服务器端口。如果指定为星号(*),这将对应所有可用的端口。
  • action参数指示规则该允许还是拒绝传入的连接请求。它有两个可能的值:allow或deny。
  • protocolList参数用来定义一个用空格分开的、应匹配的协议名称的列表。协议名称可以是:http、https、t3、t3s、giop、giops、dcom或ftp。如果没有列出任何协议,规则将会检查所有的协议。WebLogic 7.0和WebLogic 8.1版本还允许指定ldap协议。

  也可以在行中的任何位置包含“#”号。在这个符号之后一直到行尾处的所有文本都将作为注释处理。

  过滤器规则可以以两种形式定义目标参数:

  • 如果目标参数的值是主机名或IP地址,它就是“快速”规则。
  • 如果目标参数是域名,它就是“慢速”规则。

  对于快速规则,可以指定客户端的hostname(主机名)或IP address(IP地址)。IP地址后面可以跟一个可选的netmask(子网掩码),二者之间由“/”隔开。如果用户提供一个解析为IP地址列表的主机名,服务器启动时将会自动为每个IP地址生成同一规则的多个版本。这些规则被称为“快速的”,因为服务器最终拥有一个使用静态IP地址的规则列表;因此,服务器启动并运行时,不需要进行连接时DNS查找。当服务器启动并通过所有过滤器规则时,所有的主机名都被解析为它们的IP地址。下面给出快速规则的一些例子:

www.oreilly.com 127.0.0.1 7001 allow t3 # allow t3 requests from www.oreilly.com

10.0.20.30/255.255.0.0 127.0.0.1 7001 allow t3 t3s http https

  注意第2条过滤器规则是如何使用子网掩码的。

  对于慢速规则,目标参数的值是一个以星号(*)开头的域名。只有域名的头部才使用星号。下面给出慢速规则的一个例子:

*.oreilly.com 127.0.0.1 7001 allow t3

  该规则允许T3连接从运行在oreilly.com域中的主机上的任意客户端传入端口7001。它被称为“慢速”规则,因为它需要连接时DNS查找以便执行匹配,所以它肯定比快速规则要慢。

  要拒绝对服务器的所有访问,下面的规则十分方便:

0.0.0.0/0 deny # refuse the connection request

  可以在过滤器规则清单的结尾处定义这个规则,从而拒绝访问无法匹配清单中任何规则的所有连接。这样,可以确保只有当传入的连接请求匹配前面的过滤器规则之一时,才能获得允许。

安全提供程序体系结构

  现在,让我们把注意力转移到WebLogic应用程序级安全性的基础架构上。WebLogic定义了一套标准的SSPI,用于提供高级的安全服务。WebLogic还提供一组实现这些SSPI的默认安全提供程序。这些默认的安全提供程序支持并增强了基于标准J2EE角色的安全框架。事实上,还可以通过编程来控制其行为。该安全框架有两个重要的特征:

模块化

  SSPI分为很多具体的模块,这样每个安全提供程序都能够处理WebLogic安全性的各个特定的方面(例如:身份验证、授权、审计等等)。

可插入

  因为这些安全提供程序位于SSPI层之后,WebLogic使用户可以更轻松地使用自己的或第三方的实现来替换或增强默认实现。

  SSPI隐藏了安全提供程序的确切实现,从而使用户能够插入和使用自己的模块,并修改选定的安全性方面。例如,可以使用支持某种形式的生物测定识别的提供程序来替换默认的Authentication Provider,或者可以使用可以在用户登录尝试失败特定次数之后通知感兴趣的各方的提供程序来替换Auditing Provider。

  安全域是一个用户、组、角色、安全策略的逻辑分组,以及一整套安全提供程序。默认情况下,WebLogic Server带有两个这样的安全域:为WebLogic 6.x类型的安全配置提供支持的传统兼容性安全域,以及新的默认安全域。引用默认安全域通常使用它的默认名称my安全域,它是WebLogic安全提供程序的标准实现。尽管可以为一个域配置多个安全域,但是只能有一个安全域是活动的;这个活动的安全域控制了域安全性的所有方面。

  通过从Administration Console的左侧窗格中选择域,然后选择View Domain-Wide Security Settings选项,可以确定域将会使用哪个安全域。Configuration/General选项卡显示了Default Realm字段,用于指示域当前使用的安全域。Administration Console使用户可以实际地配置安全域的所有方面。可以查看和修改安全域的配置,方法是从Administration Console左侧窗格中的Security/Realms节点下选择安全域。在此,您将发现安全域中所有安全提供程序的子节点,以及对安全域的用户、组和角色的访问。

  要理解WebLogic的默认安全域的工作原理,需要理解WebLogic对资源使用的身份验证和授权结构,以及它如何与标准的基于J2EE角色的安全性相集成。本节的其余部分将专门探讨这些概念。下一小节将更详细地分析安全提供程序。

综述

  WebLogic的身份验证和授权提供程序是SSPI默认实现的一部分,它依赖于下列重要概念。

  • 用户,代表一个人、系统或Java客户端。
  • 组,代表用户的静态集合。
  • 角色,代表用户的动态集合。
  • 安全策略,定义哪些用户有权访问WebLogic资源。

  可以使用WebLogic来配置这些实体,从而保护域中的任何资源,从EJB方法调用一直到Administration Console中的特定操作。该框架禁止未授权访问,无论是从内部(例如servlet调用EJB方法)还是外部(例如Java客户端尝试使用JDBC数据源)。

  为理解这些概念,让我们参考前面第2章中的“安全性配置”部分,在这部分内容中,我们分析了如何保护web应用程序的/admin目录下的web资源。在标准的web.xml部署描述符中,我们定义了一个安全性约束,用于授权给一个称作webadmin的安全角色:

<!-- web.xml entry: -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Resources</web-resource-name>
<description>security constraints for admin stuff</description>
<url-pattern>/admin/*</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>webadmin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>

  当然,这一设置依赖于同样定义在描述符文件中的一个安全角色:

<!-- web.xml entry: -->
<security-role>
<role-name>webadmin</role-name>
</security-role>

  到此为止,我们已经发现了部署描述符中的标准J2EE安全功能。现在,我们必须把定义在web.xml文件中的安全角色指派给WebLogic Server中的一个实际的物理实体。这是通过把角色名和WebLogic Server中已配置好的许多principal(主体)相关联而实现的。web应用程序的weblogic.xml描述符文件保存了这种映射:

<!-- weblogic.xml fragment --> <security-role-assignment> <role-name>webadmin</role-name> <principal-name>jmountjoy</principal-name> <principal-name>achugh</principal-name> </security-role-assignment>

  这段XML代码片断把web应用程序中定义和使用的webadmin角色与实际的WebLogic用户jmountjoy和achugh关联起来。这样就能够禁止非webadmin角色的用户访问/admin文件夹下的web内容。现在,让我们看一看这一设置如何保护web应用程序中的web资源。

  受保护的资源将访问权限限定为仅针对用户的一个子集。任何满足对受保护资源的约束的用户就有权访问该资源。WebLogic可以允许用户保护各种资源:web应用程序、URL(就像前面的例子中的那样)、单个EJB方法、web服务、连接池,甚至还包括JNDI树的分支。例如,可以确保只允许特定的用户访问连接池或者调用受保护EJB上的方法。在示例web应用程序中,匹配 /admin/* 模式的URL集代表一项受保护资源。这意味着可以轻松建立一个安全的环境,在这个环境中,应用程序必须遵守制定的安全约束。WebLogic还使用户可以根据需要轻松地修改很少的代码来改变配置。在示例应用程序中,安全约束是声明性地定义在部署描述符中的。因此,可以调整安全设置,而不用修改代码。

  访问控制机制依赖于通过身份验证的用户这个概念。该用户代表着一个已通过身份验证的实体——它可能是一个人(就像在本例子中)或者一个外部客户端程序。用户可以通过不同的方式对其进行身份验证。在Web上,用户可能需要填写一张登录表单。另一方面,Java客户端应用程序可能要依赖于JAAS身份验证来建立与WebLogic Server之间的信任。在我们的例子中,用户是由通过Web提供的用户名和密码(登录证书)确定的。通常,作为身份验证的结果,一个用户可能拥有大量与其相关的主体(身份)。例如,在身份验证成功完成之后,与系统用户相关联的主体就包括系统用户本身和它所属的组——即Administrators组。一些用户可能根本不需要进行身份验证,在这种情况下,它们将保持匿名。

  当域保存了大量WebLogic用户时,管理每个单独用户的安全需要就变成了一件麻烦的事情。因此,WebLogic使用户可以配置静态的用户集合,称为组。从安全性的观点看,如果把角色或策略语句应用于一个组,该角色或策略就会被指派给该组的所有成员。从管理的观点看,管理几个组比管理(可能)几百个用户要容易得多。记住,组是静态的用户集合。管理员在配置时显式地定义组的成员。就像我们在前面所看到的那样,组还可以作为安全性主体。所以,举例来说,weblogic.xml描述符文件可以很容易地把安全角色映射为现有组的名称:

<!-- weblogic.xml fragment -->
<security-role-assignment>
<role-name>webadmin</role-name>
<principal-name>someAdminGroup</principal-name>
</security-role-assignment>

  在这个例子中,对web内容的访问被限定为仅针对someAdminGroup中的所有用户。

  安全角色代表动态的用户集合,这个集合的成员是在运行时基于subject的主体和其他成员资格标准确定的。一个用户是否属于某个角色取决于该用户是否在运行时满足该角色的成员资格条件。可以为一个角色指定多个成员资格条件。这些条件包括用户名、组名和一天中访问时间的逻辑组合。

  例如,可以把DayShopper角色的成员资格条件定义为“属于Shopper组而且访问时间在上午8:00到下午5:00之间的任何用户”。可以给一项资源指派多个角色,从而帮助指定资源的授权条件。注意,角色本身不能保证访问控制,它们不过是有助于最终保护对目标资源的访问的策略语句定义。在前面的例子中,我们创建了一个称为webadmin的角色。该角色的成员资格条件很简单:客户端必须首先作为jmountjoy或achugh通过身份验证,然后web应用程序才会认为它属于webadmin角色。

  可以通过为WebLogic资源定义策略语句对该资源进行保护。安全策略是有关访问的语句——它决定了哪些用户可以访问资源。和角色一样,可以为策略定义一个包含很多条件的逻辑组合:用户名、组名、一天中的访问时间和角色名。例如,可以给一个JDBC池指派下面的策略:“调用者必须属于DayShopper角色或Administrators组。”这意味着,只有属于Administrators组的已验证用户或符合DayShopper角色的成员资格标准的用户才可以访问这个池。如果任何用户在进行这些为JDBC池定义的访问控制检查时失败,WebLogic将抛出一个授权异常。

  现在,让我们针对这些概念再次分析一下web应用程序先前的安全约束。weblogic.xml描述符文件定义了一个webadmin角色。部署时,WebLogic读取这个描述符文件,并在它内部的安全配置中创建一个webadmin角色。这个内部安全角色被配置为确保只有用户achugh和jmountjoy才有成为这个角色成员的资格。因此,J2EE角色映射到WebLogic角色,而角色到(一个或多个)主体(role-to-principal(s))的指派为内部角色定义了成员标准。

此外,WebLogic创建并指派了一条策略语句给保护所有匹配URL模式 /admin/*的web资源的web应用程序。该策略语句将授权给任何满足以下条件的调用者:“调用者属于webadmin角色。”通过这条策略语句,WebLogic可以确保,任何不是webadmin角色成员的用户不能访问/admin文件夹下的web内容。因此,WebLogic依赖于一条幕后的策略语句来实施部署描述符所定义的安全约束。稍后,我们将说明如何显式地创建用户自己的策略语句。

用户和组

  为列出属于某个安全域的用户,从Administration Console选择该安全域,然后选择Users节点。然后,可以使用右侧窗格来查看所有用户或者过滤清单。System用户帐号也将是清单的一部分——这是当使用Configuration Wizard(配置向导)创建域时定义的Administration用户帐号。选择“Configure a new User”,创建一个新用户。需要为每个用户指定一个名称、一段简短的描述和一个密码。注意,安全域中所有的用户名必须是独一无二的。默认的提供程序使用不区分大小写的用户名。用户可以属于一个或多个组。

  为列出和编辑属于某个安全域的所有组,需要从Administration Console选择该安全域,然后选择Groups节点。还可以在这里创建一个新组。组的Membership选项卡可能会误导人,因为它并不允许查看组的成员。要查看一个用户是不是组的成员,必须选择该用户,然后查看它的Groups选项卡。WebLogic允许向其他现有的组添加组,而Membership选项卡列出了所选中的组中包含的所有子组。还可以使用这个选项卡给当前组添加另一个组。

  对于安全配置,组成员资格具有两点重要的含义。假定用户在域中定义了两个组,A和B,而组B是组A的一个成员。这意味着:

  • 属于组B的每个用户同时也属于组A。
  • 如果指派一个角色或策略给组A,就是同时向组A的所有成员和组B的所有成员指定了相同的角色或策略。

  当查看用户的Groups选项卡时,Administration Console仅列出该用户直属的组。所以,如果一个用户属于组B,Administration Console在Groups选项卡下只会列出组B,即使该用户实际上既属于组A,也属于组B。

  当使用Configuration Wizard创建一个新域时,以下组将会自动创建并随时可用:Administrators、Deployers、Operators和Monitors。一开始,System用户是惟一被创建的用户,它也是域中Administrators组的惟一成员。

  记住,组只不过简化了管理的任务。如果一个用户是某个组的成员,它不会自动获得任何特殊的权限。只有当组(直接地或通过一个角色)参与策略语句时,它才会继承访问权限。例如,最初的System用户帐号获得了Administrative访问权限,仅仅是因为它是Administrators组的成员,而这个组又是(全局的)Admin角色的一个成员,同时有一条可用的策略语句把访问域中各个区域(area)的权限授予Admin角色。

  有两个组在Groups页面上没有列出,但是它们自动对于安全域可用:

users
该组代表所有通过身份验证的用户的集合。任何成功通过身份验证的用户都是users组的成员。

everyone
这个组代表所有WebLogic用户的集合,包括匿名用户。任何用户,无论是已验证的还是匿名的,都是everyone组的一个成员。

  这些组为建立默认的访问控制提供了一种便捷的方式。例如,通过策略语句“用户是everyone组的成员”,资源可以被所有用户访问。另外,通过对某项资源定义如下策略:“用户是users组的成员”,可以把访问权限定为仅针对已验证的用户。还可以编程式地检查服务器端的组成员资格。下面的例子用于检查当前用户是users组还是everyone组的成员:

/** returns false if executed without any security context */

weblogic.security.SubjectUtils.isUserInGroup(

 

weblogic.security.Security.getCurrentSubject( ),"users");/** returns true regardless of whether the user authenticates */

weblogic.security.SubjectUtils.isUserInGroup(

weblogic.security.Security.getCurrentSubject( ),"everyone");

保护用户帐号

  WebLogic提供一种用户封锁功能,以防止用户帐号的滥用。当一个用户尝试登录失败的次数达到一个阙值时,该用户就会被封锁。当这种情况发生时,该用户将被封锁一段时间(时间长短可以配置),或者直到管理员解锁该用户为止。在这期间,该用户被禁止使用这些证书访问服务器。为配置用户封锁,需要选择Administration Console左侧窗格中的Security/Realms节点下的安全域。然后,可以使用User Lockout选项卡来调整封锁功能,并查看封锁统计信息。

  表17-2列出了User Lockout选项卡下可用的各种配置选项。默认情况下,这些设置被配置为最高安全性。

表17-2. 配置用户封锁

设置

描述

默认值

Lockout Enabled

该设置表明是否启用封锁功能。如果使用另一种可选的Authentication Provider(它使用自己独有的保护用户帐户的机制),需要禁用这项功能。

true

Lockout Threshold

该设置决定了在封锁用户之前,允许登录尝试失败的最大次数。

5

Lockout Reset Duration

假定Lockout Threshold是5,而Lockout Reset Duration是3分钟。如果一个用户在3分钟之内进行了5次失败的登录尝试,该用户帐户将被封锁。如果这5次失败的尝试并非发生在3分钟之内,那么该帐户仍然保持活动。

5分钟

Lockout Duration

该设置决定了被封锁之后,用户无法访问其帐号的持续时间(以分钟为单位)。

30分钟

Lockout Cache Size

该设置指定用于保存无效登录尝试的缓存大小。

5

Lockout GC Threshold

该设置决定了内存中保存的无效登录尝试的最大值。当无效登录记录的数目超过了这个值,WebLogic的垃圾收集器就会删除所有到期的记录——此时相关的用户已经被封锁。

400

  当一个用户被封锁时,用户列表(位于Users节点下)中的Locked栏下就会出现一个Details链接。如果选择列表中某个用户的这个链接,就可以查看该用户登录尝试失败的次数,以及最后一次失败的登录尝试的时间。还可以选择Unlock选项,手动重新激活用户的帐户。

角色

  和组不同,角色代表一个动态的用户集合。角色成员资格可以通过以下规则进行定义:

用户名

  可以指定多个用户名。如果通过身份验证的用户与列表中的一个名称相匹配,而且它满足其他所有规则,它将自动成为该角色的成员。

组名

  可以指定多个组名。如果通过身份验证的用户是列表中某个组的成员,而且它满足其他所有规则,它将自动成为该角色的成员。

访问时间

  可以定义多个允许用户进行访问的时间段。如果用户试图在一个指定的时间段之内访问资源,而且满足其他所有规则,它将自动成为该角色的成员。

  通过使用逻辑AND(与)和OR(或)关系,可以以各种方式组合这些规则。例如,可以基于如下规则创建RoleA:用户属于组UKSeller,而且访问时间在上午8:00到下午9:00之间。那么任何试图在这段时间内访问资源,同时又是UKSeller组成员的用户就会成为RoleA的成员。或者,可以基于如下规则创建RoleB:用户属于组UKSeller,或者访问时间在上午8:00到下午9:00之间。在这种情况下,组UKSeller的每个成员都将始终属于这个角色,同时每个在上午8:00到下午9:00之间访问资源的用户也将成为该角色的一个成员,而不管它属于哪个组。当用户尝试访问受(根据该角色定义的)策略语句保护的资源时,要在运行时对该角色的成员资格条件进行评估。因此,成员资格条件有助于评估在某个时刻用户是否属于该角色。

  通常,WebLogic默认的Role Mapping Provider负责管理与在某个安全域中定义的所有角色相关的信息。事实上可以定义两类角色:全局的(scoped)和局部的(scoped)角色。

全局角色

  全局角色可用于安全域中的所有资源。当创建一个新域时,就会自动创建一组默认的全局角色;它用于授权对各种操作的访问。这些预定义的全局角色与默认的安全策略(对WebLogic域执行factory-set安全配置)相关联:

Admin
  属于该角色的用户对域的各个区域具有完全访问权。这包括以下能力:查看和编辑域配置、启动和停止服务器、部署应用程序(EJB、JMS factory、web应用程序)等等。任何属于Administrators组的用户将自动继承Admin角色。也就是说,Admin角色的成员资格条件是用户必须属于Administrators组。

Deployer
  属于该角色的用户可以查看域配置,查看和编辑部署描述符,部署应用程序和EJB,以及启动和关闭类、J2EE连接器和web服务组件。Deployer角色的成员资格条件是用户必须属于Deployers组。

Operator
  属于该角色的用户可以查看服务器配置,还可以启动、停止和重新开始服务器实例。Operator角色的成员资格条件是用户必须属于Operators组。

Monitor
  属于该角色的用户只可以查看服务器的配置。Monitor角色的成员资格条件是用户必须属于Monitors组。

  为创建或修改现有的全局角色,需要从Administration Console左侧窗格中选择安全域,然后选择Global Roles节点。

  WebLogic还提供一个称为anonymous的全局角色。它的成员资格被定义为包括everyone组中的所有用户。即使anonymous角色没有出现在Administration Console中所列出的角色之中,仍然可以使用它来定义针对资源的策略。

局部角色

  大多数角色是局部的,这是指它们适用于特定的资源或JNDI树的分支。全局角色和局部角色的差别在于,前者独立于任何资源,并且可以通过Administration Console进行集中管理,而后者是跨各种资源分布的。用户必须选择一种特定的资源,以便查看相关的局部角色。不管实际资源是什么,用于创建局部角色的底层principle是相同的。从Administration Console的左侧窗格中定位资源,然后右击并选择Define Scoped Role。在某些情况下,在更详细的方面中可以定义局部角色及其“兄弟”,局部策略。例如,在web应用程序中,可以为EJB(基于每个方法)、web服务(基于每项操作)和web资源(基于某种HTTP方法类型(POST、GET、HEAD等等))都定义一个局部角色和策略。现在,让我们看一看如何为特定的资源创建局部角色,以及在此配置中需要采取的一些预防措施。

连接池和多池

  JDBC资源位于Services/JDBC子树下。可以右击选定的资源(如:连接池),然后选择Define Scoped Role来为资源定义一个角色。还可以删除或修改以前指派的角色。

  JDBC角色是分级的。如果右击JDBC/Connection Pools节点,可以按照同样的过程创建一个适用于所有连接池的局部角色。

JNDI分支

  可以为服务器的JNDI树的特定的节点或分支指派一个角色。从Administration Console的左侧窗格中选择该服务器,然后右击并选择“View JNDI tree”选项。将出现一个新的浏览器窗口,显示选中的服务器的JNDI树。然后,选择树中的任意节点,右击,并选择Define Scoped Role选项。

Web应用程序

  为web应用程序指派角色和策略有点不同,因为对于web应用程序中的特定URL来说,角色和策略是局部的。从Administration Console的左侧窗格中选择web应用程序,然后选择Define Scoped Role选项。接着,会要求用户提供一个URL模式和一个用于限制对该URL模式的访问权的角色。稍后,通过使用相同的URL模式和局部角色,可以将一条策略语句应用于web应用程序。例如,用户可能希望把角色和策略的作用域限定为只针对特定的servlet,这种情况下可以使用URL模式,比如 /servletname。如果想使角色应用于web应用程序中的所有资源,使用URL模式 /*。

Web services

  Web服务组件通常打包在一个EAR文件中。通过展开Deployments/ Applications节点下代表应用程序的节点,可以定位web服务。在WebLogic 7.0中,可以在Deployments/Web Services节点下定位web服务。

  右击服务,然后选择Define Scoped Role选项。这会要求用户为选中的web服务模块中的所有服务定义一个角色。还可以选择Define Policies and Roles for Individual Services选项,这将提供一个列出了所有的web services的表。对于每个web服务,可以选择Define Scoped Role选项,以便为该web服务单独创建一个局部角色。当以这种方式定义一个局部策略时,还能够选择将策略应用于哪项操作。

  web服务角色和策略是分级的。其实,如果使用Define Roles选项在一个web服务模块上设置一个角色或策略,该模块中的所有服务都将继承该角色或策略。还可以对捆绑web服务模块的应用程序设置策略。在这种情况下,所有的web服务模块和这些模块中所有的web服务将继承该角色和策略。

EJB

  为EJB指派局部角色非常类似于为web服务指派局部角色。如果选择EJB Modules节点,所有EJB都将继承用户定义的任何角色或策略。如果选择一个特定的EJB模块,并选择Define Scoped Role选项,用户定义的任何角色的作用域都将被限定为针对该模块中的所有EJB。最后,如果选择Define Policies and Roles for Individual Beans选项,将得到一个EJB清单,从而允许为每个EJB单独指定局部角色或策略。如果以这种方式为特定的EJB定义一个策略,还可以指定把该策略应用于哪些EJB方法。另一种为应用程序中的所有EJB定义局部角色的方法是只定义一个全局角色。

JMS destination

  为给JMS destination指派局部角色,需要选择在其驻留的JMS服务器节点下选择JMS destination,右击,然后选择Define Scoped Role选项。

使用部署描述符

  对于J2EE组件(例如:EJB、web应用程序),可以从部署描述符获得角色信息,这一点在前面的web应用程序例子中已经演示过了。当部署J2EE组件时,角色会自动创建,并填充以部署描述符中保存的数据。如果接着更改新的安全角色,这些更改不会回存到部署描述符中。理论上来说,部署了J2EE组件之后,需要重新配置WebLogic,这样当重新部署该组件时,就不会刷新角色。稍后,我们将讨论如何通过指示安全提供程序忽略部署描述符中的安全约束,改变它们的这种默认行为。

外部定义的元素

  回忆一下,我们是如何使用web应用程序的weblogic.xml描述符文件,把先前在标准的web.xml描述符文件中定义的安全角色映射为WebLogic安全域中的实际主体。例如,weblogic.xml描述符文件中的以下部分显示了如何列出与角色mysecrole相关联的主体:

<security-role-assignment>
<role-name>mysecrole</role-name>
<principal-name>jon</principal-name>
<principal-name>system</principal-name>
</security-role-assignment>

  作为一个替代方案,还可以使用外部定义的 * 元素来表示WebLogic,web.xml描述符文件中定义的安全角色实际上指向安全域中使用Administration Console手动创建的一个角色。这种方法意味着无需显式地把安全角色映射为现有的WebLogic用户和组。相反,可以将安全角色的成员资格条件延迟到web应用程序部署之后。例如,假定web应用程序的weblogic.xml描述符文件包括如下的安全信息:

<security-role-assignment>
<role-name>mysecrole</role-name>
<externally-defined/>
</security-role-assignment>

  这表明,web应用程序的描述符的安全约束依赖于一个已经为安全域配置的、称为mysecrole的角色。当部署web应用程序时,WebLogic将在其安全域中查找mysecrole角色,并使用这个安全角色在web应用程序上配置策略语句。在本例中,策略语句将指定以下条件:“调用者是mysecrole角色的成员。”这样,WebLogic就可以确保只有是安全角色mysecrole的成员的用户才能调用受保护的资源。当然,现在必须使用Administration Console为安全域配置mysecrole,使其作为这个特定的web应用程序的全局角色或是局部角色。类似的技术也可以对EJB使用。

  外部定义元素的一个重要的优点就是,无需修改WebLogic处理部署描述符中安全信息的方式(参见本章后面的“忽略部署描述符”一节)。因为安全约束是通过根据安全角色而定义的策略语句实现的,而安全角色只能使用Administration Console填充,所以没有机会重写这种角色和策略指派。该元素和传统的J2EE角色指派之间的区别在于,任何列出了weblogic.xml描述符文件中的主体的安全角色指派都将创建一个角色,此角色的成员资格条件是根据这些主体而定义的。如果使用外部定义元素,安全角色指派必须指向已经使用Administration Console为安全域配置的角色。

策略

  安全策略使用户可以保护各种服务器资源。例如,可以决定谁可以访问Administration Console、谁可以启动和停止服务器,以及谁可以访问连接池、web应用程序、EJB、企业应用程序、J2EE连接器和JNDI树的特定分支,等等。安全策略非常严密地控制着WebLogic域中的授权设置。尽管局部角色看起来十分类似于策略,但是策略定义了访问控制,而角色则不然。总之:

  • 策略语句用于保护资源。
  • 策略语句允许用户指定多个条件,满足这些条件的用户就可以访问资源。

  安全策略是对角色有效的条件的超集。可以使用用户名、组名、定时设置和角色的一个逻辑组合来定义策略。策略中使用的角色可以是全局角色,也可以是那些作用域限定于为其定义策略的资源的局部角色。

  注:WebLogic资源只有当指派了安全策略后才受到保护。某些WebLogic资源带有一组默认策略。

 角色信息是由Role Mapping Provider保存的,而策略信息则是由Authorization Provider保存的。即使可以以与角色相同的方式配置安全策略,我们还是建议设置角色来识别用户职责,并创建策略以使用这些角色指定访问限制。也就是说,应该根据现有用户、组和定时设置来定义角色,然后就可以使用这些角色为资源配置策略语句。这种模式与开始“综述”一节中讲述的基于J2EE角色的安全性模型十分吻合。

  有很多指派策略的方式:

  • WebLogic可以自动指派策略给web应用程序和EJB,不过要在读取了它们的部署描述符之后。
  • 管理员可以手动为WebLogic资源指派策略,并改变它们的配置。
  • WebLogic提供了适用于很多资源的默认安全策略。

使用Administration Console

  管理员可以显式地定义有助于保护WebLogic资源的安全策略。就像为资源定义局部角色一样,可以以同样的方式指派安全策略。只要从Administration Console的左侧窗格中选择资源,然后右击并选择Define Security Policy选项即可。EJB提供了另外的选项,即“Define Security Policies and Roles for Individual beans”,该选项允许为特定的EJB定义策略,以及进一步将此策略限定于选中的EJB方法。Web服务模块也提供类似的功能,允许为模块中特定的web服务定义策略,以及进一步将此策略限定于选中的web服务操作。也有针对JMS destination的相同功能,只不过策略是限定于队列的发送、接收或浏览操作,或者是主题的发送或接收操作。

启用用户定义的策略

  在WebLogic 8.1中,默认情况下,使用Administration Console创建的新策略是不会得到应用的。相反,只有那些使用部署描述符定义的策略才会生效。例如,如果为web应用程序中所有的.html文件添加新的局部策略,假定部署描述符中没有定义这种安全约束,那么新的局部策略就不会生效。为了切换这种行为,需要从Administration Console的左侧窗格中选择security realm,然后选择General选项卡。Check Roles and Policies 设置有两个可能的值。

Web Applications and EJBs Protected by DD
  该选项确保WebLogic只认可那些定义在web应用程序和EJB模块的部署描述符中的安全约束。这是安全域的默认行为。

All Web Applications and EJBs
  该选项确保WebLogic认可使用Administration Console为web应用程序和EJB模块配置的任意安全策略。

  因此,如果需要启用使用Administration Console定义的策略,必须把Check Roles and Policies设置的值修改为后一种选项。

使用部署描述符

  WebLogic支持J2EE安全性模型,该模型依赖于定义在描述符文件中的安全角色来决定访问权限。当部署EAR或WAR时,WebLogic的Authorization Provider就会检查部署描述符,并基于配置的设置创建内部的安全角色。另外,提供程序还定义了一个安全策略,用于授权给属于这些角色的所有主体。稍后,我们将讨论如何通过指示提供程序忽略部署描述符中所保存的安全数据,改变提供程序的默认行为。

默认策略

  WebLogic带有许多默认的安全策略——例如,WebLogic支持的一个默认策略限制对Administration Console的访问。以下安全策略均基于角色成员资格:

管理性资源

  Administration Console和其他管理性资源受一个安全策略的保护,该安全策略要求调用者是以下角色之一:Admin、Deployer、Operator或Monitor.

服务器资源

  Administration Console中Server节点下的资源受到一个安全策略的保护,该安全策略要求调用者属于Admin或Operator角色。

COM资源

  Administration Console左侧窗格中Services/jCOM节点下的资源受到一个安全策略的保护,该安全策略要求调用者属于JCOM角色。

  默认情况下,所有特定于应用程序的资源,比如那些与JDBC、JMS、EJB、EIS、MBean和Web Services相关的资源,对于所有用户都是可访问的。这是因为这些资源是受默认策略保护的,而此默认策略要求调用者属于everyone组。始终可以查看应用于WebLogic资源的默认安全策略。例如,如果右击Services/JDBC节点下的Connection Pool节点,然后选择Define Security Policy选项,就可以查看所有连接池的默认策略。

  当配置一项新的资源时——例如,一个新的JDBC池或web services组件——它将自动继承默认的安全策略。任何与资源相关的新安全策略也会使用所继承的策略条件。然而,如果使用新的策略条件为资源定义新的安全策略,这些设置将会重写所继承的策略条件。也就是说,如果为资源定义一个策略,那么所继承的策略条件就会被忽略。例如,如果为JDBC池定义一个策略约束,要求调用者属于角色MyRole,它将覆盖默认的策略约束,即调用者属于everyone组。

忽略部署描述符

  部署应用程序时,WebLogic会检查部署描述符中定义的安全约束,并在各个提供程序中建立适当的角色和策略语句。因为这些角色和策略语句不会保存到部署描述符中(而是保存到内部存储器中),下次部署应用程序时如果再读取描述符文件中的信息,WebLogic就会重写对角色和策略信息所做的任何更改。可以预防这种重写行为,方法是指示WebLogic在下次部署应用程序时忽略部署描述符中的安全约束。为这样配置,需要使用Administration Console的左侧窗格导航到security 安全域,然后在General选项卡中修改On Future Re-Deploys* 属性的值。这项设置的默认值(即initialize roles and "policies" from DD)确保WebLogic会基于部署描述符中保存的安全信息创建角色和策略。如果将该属性的值设置为“ignore roles and policies from DD”,就可以防止WebLogic读取保存在部署描述符中的安全信息。

  因为提供程序管理所有有关角色和策略语句的信息,既然可以决定何时WebLogic应该忽略部署描述符中的安全数据,就可以更好地控制这些访问控制信息。有两个基本的选择,每个选择都有各自的安全含义:

  • 如果选择在实际部署应用程序之前忽略部署描述符,需要从Administration Console手动配置应用程序的安全约束。提供程序将在它们自己的存储器中保存访问控制信息,而部署描述符中的安全数据将完全被忽略。
  • 如果选择在部署应用程序之后忽略部署描述符,这时提供程序已经使用了描述符文件中的安全约束,稍后就可以从Administration Console进一步改进它们。再次强调,提供程序将在它们自己的存储器中保存这些信息。然而,因为描述符文件中的安全设置已经被忽略,它们就不会覆盖用户对角色和策略语句所做的任何更改。

小结

图17-1总结了我们所描述的安全架构。

图17-1. 身份验证组件的静态结构

  从上图可以看出,用户可以属于组,而组可以包含其他组。角色可以根据用户和/或组来定义。对于特定种类的资源来说,角色可以是全局的或局部的。这里没有显示出所有的资源——只有分级的连接池资源。特定的连接池包含在Connection Pools资源中。

  注:严格来说,策略是应用于ResourceMBean的。运行时,ResourceMBean的存在代表每个实际的JDBC Connection Pool,它们都被扩展为代表保存所有连接池的“容器”的另一个MBean。策略的继承仍然有效,因为ResourceMBean以这种方式相互扩展。

  局部角色和策略要么与Connection Pools容器相关联(在这种情况下,由它的所有实例所继承),要么与特定的JDBC Pool本身相关联。所有策略都是局部的,因为它们始终与特定的资源相关联。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有