使用 Geronimo 构建安全的企业基础设施

Geronimo 健壮安全特性的一个现实世界的演示

Comments

业务场景

现代企业通常是每天都面临大量机会和挑战的复杂系统。其中许多挑战可以让企业的 IT 基础设施面临风险,所以确保尽可能最高级别的 IT 安全是至关紧要的。Apache Geronimo 应用服务器支持中小企业应用程序,并为最新的 J2EE 规范提供健壮安全的支持。使用 Geronimo 应用服务器允许建立符合最新标准的安全的企业基础设施。为了演示 Geronimo 的安全特性,IBM 专家团队实现了一个简单银行场景的模拟器,以展示 Geronimo 在现实世界业务场景中的技术能力。

用作示例的银行业务场景实现了一个资金转帐用例。需要从帐户转帐资金的零售银行客户和监督所有交易的审计员(称作用户)可以访问应用程序。主要的安全假设是零售银行客户不能查看其他用户的帐户,而审计员可以访问应用程序正在执行的所有交易 —— 使审计员充当管理员或超级用户的角色。

应用程序允许零售银行客户:

  • 登录以输入认证和帐户访问授权的凭证。
  • 查看帐户信息。
  • 通过选择资金金额和转帐目的地来启动转帐。
  • 检查已启动转帐的状态和历史。

应用程序允许银行审计员:

  • 登录以作为超级用户输入认证和授权的凭证。
  • 检查系统正在处理的所有交易。

图 1 所示的屏幕截图展示了启动资金转帐时显示给零售银行客户的界面。

图 1. 资金转帐启动界面
资金转帐启动界面
资金转帐启动界面

本文重点介绍保护机密信息和防止中间人(man-in-the-middle) 攻击,在这种攻击中,入侵者截取并修改服务器和客户机之间的流量。交易机密性通过认证和授权设施来实现。传输层和应用层都有这些设施。HTTPS 用作传输层的认证和授权设施,J2EE 安全用作应用层的认证和授权设施。

图 2 展示了应用程序的高级系统视图。

图 2. 应用程序的系统视图
应用程序的系统视图
应用程序的系统视图

图 2 所示,客户机组件表示一个具有用于访问应用程序的 Web 浏览器的计算机。客户机通过 HTTPS 协议与 Web 接口交互。该协议用于提供安全信息(比如用户凭证和交易信息)的机密性,还提供了防止中间人攻击的保护。对特定页面的访问使用 J2EE 声明性和程序性安全来限制,以禁止对页面的非授权访问。

Web 接口由多个 Web 页面和 Java servlet 组成。Servlets 使用 Enterprise JavaBeans (EJB) 调用将所有请求重定向至业务逻辑层。所有业务逻辑 EJB 方法使用 J2EE 声明性和程序性安全来保护,以在它们被不是应用程序 Web 接口的一些组件调用时禁止未授权访问。

业务逻辑组件由无状态 EJB 和多个数据 JavaBeans 组成。无状态 EJB 使用本地 EJB 调用来访问持久层,因此实体 bean 的方法不用 J2EE 安全来保护。

持久层由多个 Container-Managed Persistence (CMP) EJB 组成。通过 Java Database Connectivity (JDBC) 访问数据库。数据库访问安全依赖于 JDBC 驱动程序和数据库实现。出于本文目的,数据库管理系统与应用服务器并置。因此,应用程序假设对数据库进行独占访问。

解决方案中使用的数据库服务器被部署到嵌入 Geronimo 中的 Apache Derby 数据库管理系统中(参阅 参考资料 以链接到 Apache Derby 站点)。数据库包含业务信息(比如帐号),以及安全相关数据(比如用户凭证)。

设置 Geronimo 应用服务器安全

本节介绍配置 Geronimo 应用服务器安全需要遵守的步骤。其中包括设置 HTTPS 支持,以及配置 J2EE Web 和 EJB 安全。

HTTPS 配置

作为第一步,需要配置 Web 容器的 HTTPS 传输。HTTPS 是 HTTP 协议在 Secure Sockets Layer/Transport Layer Security (SSL/TLS) 协议上的实现(参阅 参考资料 以获得更多信息)。

解决方案使用 HTTPS 传输来保护在服务器和客户机之间传递的重要信息,比如用户凭证。因为 Geronimo 应用服务器的最新快照预配置有 HTTPS 传输,所以只需将正确的证书放置到 Geronimo 的证书存储中。Geronimo 发行版提供的默认证书是自签发的,可用于应用程序开发中。

有关证书的更多信息,请参阅 Sun Java keytool 实用程序的手册(参阅 参考资料)。将证书文件放置在 Geronimo 安装的 var/security 子目录中。

配置一般安全

配置完 HTTPS 传输之后,必须在特定于 Geronimo 的部署描述符(部署计划)中配置安全。这可以通过更新应用程序范围的部署计划、EJB 模块部署计划或 Web 模块部署计划来实现。

首先,声明应用程序角色和特定主体之间的映射。对于每个安全角色,必须声明相应的主体类及其名称。清单 1 中的代码示例提供了此类配置的一个示例。

注意 清单 1 中的下列内容:

  • 名称为 auditor 的主体 org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal 映射到审计员应用程序角色。
  • 名称为 user 的主体 org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal 映射到用户应用程序角色。
  • 名称为 system 的主体 org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal 在用户不进行认证时用作默认主体。

配置安全领域

下一步是配置 安全领域,安全领域定义用户凭证(用户名和密码)与用户角色之间的映射。角色稍后用于检查用户是否被授权访问特定资源(比如查看 Web 页面)。

配置安全领域需要配置三个 GBeans(参阅 参考资料 以链接到 GBeans 的说明):一个用于登录模块,一个用于登录模块使用,一个用于领域本身。

该登录模块提供了特定部分的认证。清单 2 展示了配置 SQL 登录模块的示例。

清单 2 中,workdev-sql-login 是一个登录模块,被配置为使用 SQL 数据库作为凭证来源。指定了两个 SQL 查询 —— 一个用于选择用户和相应密码的列表,另一个用于选择用户名和组名之间的映射。

使用 JDBC URL 中指定的 JDBC 驱动程序访问数据库。Geronimo 还提供了 Apache Derby,这是一个关系数据库,在示例应用程序中用来存储用户凭证。一定要注意,解决方案以两种不同的方法访问其数据库 —— 使用被部署为应用程序一部分的 DataSource,从 SQL 登录模块访问和从 EJB 模块访问。因为单个 Derby 数据库实例被限制为只允许通过由同一个类装载器装载的 JDBC 驱动程序进行的同时访问,所以数据库配置和 SQL 登录模块配置必须部署为单个应用程序的各个部分。

另一个 GBean 被配置来指定登录模块用于领域中。该 GBean 列出登录模块,并声明所需的登录模块。清单 3 展示了此类配置的一个示例:

清单 3. 登录模块配置
<gbean name="workdev-sql-modules"
    class="org.apache.geronimo.security.jaas.JaasLoginModuleUse">
    <attribute name="controlFlag">REQUIRED</attribute>
    <reference name="LoginModule">
        <name>workdev-sql-login</name>
    </reference>
</gbean>

controlFlag 属性指明该登录模块用于为要认证的用户返回有效结果。LoginModule 属性引用指向登录模块配置。

另一个 GBean 定义安全领域本身。配置包括指定领域名称和引用 GBean,GBean 用于配置构成领域的登录模块列表。清单 4 展示了此类配置的一个示例。

清单 4. 定义领域
<gbean name="workdev-sql-realm"
    class="org.apache.geronimo.security.realm.GenericSecurityRealm">
    <attribute name="realmName">WorkdevRealm</attribute>
    <reference name="LoginModuleConfiguration">
        <name>workdev-sql-modules</name>
    </reference>
</gbean>

完成这些配置步骤之后,可以配置 J2EE 安全设施来保护应用程序组件。

配置 Web 层 J2EE 安全

Geronimo 支持 Web 层的声明性和程序性安全。下文介绍这两种安全。

声明性安全

声明性地保护 Web 层意味着显式指定需要用户认证的页面。

要使用声明性安全方法,必须在 web.xml 部署描述符中指定所有可能的安全角色。清单 5 展示了此类规范的一个示例。

清单 5. 声明性安全
<security-role>
	<description>Usual user</description>
	<role-name>user</role-name>
</security-role>

security-role XML 元素包含单个安全角色的声明。该描述元素包含角色的文本描述,而 role-name 元素定义角色名称本身。

声明之后,角色可用于限制对特定 Web 页面的访问。这通过 Web 部署描述符中的 security-constraint 元素来实现。该元素描述要保护的页面集合和关联的安全约束。清单 6 展示了一个使用 /user/* URL 掩码保护所有页面的示例。

清单 6. 指定安全约束
<security-constraint>
<web-resource-collection>
		<web-resource-name>UserArea</web-resource-name>
		<description>User accessible pages</description>
		<url-pattern>/user/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<description></description>
		<role-name>user</role-name>
	</auth-constraint>
</security-constraint>

web-resource-name 元素包含 Web 资源的名称。description 元素包含集合的文本描述。web-resource-collection 元素指定要保护的页面的模式,这是集合定义中最重要的信息。

auth-constraint 元素用于指定对通过认证的用户帐户的约束,这些约束必须在访问受保护页面之前得到满足。该元素包含约束描述和角色名称(先前在部署描述符中定义过)。

程序性安全

在 Geronimo 中实现的程序性安全的工作方式与 J2EE 1.4 规范中描述的一样。但是,目前它包含一些与传递安全上下文相关的设计缺陷,稍后将讨论。

在已实现的解决方案中,程序性安全用于实现成功授权后将用户重定向至相应页面的 servlet。该 servlet 的目标是验证用户角色是否已通过认证,并将审计员重定向至审计员页面。其他所有用户被重定向至转帐页面。

清单 7 展示了在 servlet 中实现的业务逻辑。

清单 7. 程序性安全示例
if(req.isUserInRole("user")) {
       resp.sendRedirect("user/transfer");
} else if(req.isUserInRole("auditor")) {
       resp.sendRedirect("auditor/viewOrders");
}

为了让安全实现正确发挥作用,servlet 被放到受保护区域,以便只有通过认证的审计员和用户可以访问。实现方法与上述让页面只能由用户访问的方法相似。

EJB 安全

Geronimo 支持 J2EE EJB 声明性和程序性安全。在本文描述的示例应用程序中,保护业务逻辑 EJB,以使只有通过认证的用户可以调用特定的 EJB 方法。这可以通过声明性或程序性安全来实现。

声明性安全

声明性地保护 EJB 方法按照 J2EE 规范进行。首先,在 EJB 部署描述符中声明安全角色,如 清单 8 所示。

清单 8. 声明安全角色
<security-role>
    <description>User role</description>
    <role-name>user</role-name>
</security-role>

然后,声明执行特定方法所需的权限。下列代码示例来自 EJB 部署描述符,如 清单 9 所示。

清单 9. 设置 EJB 方法的权限
<method-permission>
    <role-name>user</role-name>
    <method>
        <ejb-name>BusinessLogic</ejb-name>
        <method-intf>Remote</method-intf>
        <method-name>getOwnOrders</method-name>
        <method-params>
             <method-param>java.lang.String</method-param>
        </method-params>
    </method>
</method-permission>

清单 9 中,只有被授权的零售银行客户才能调用该方法。

对于 CMP EJB,它们的方法被标记为 unchecked,所以在调用期间不检查权限。清单 10 展示了这种配置的示例。

清单 10. 将 EJB 方法标记为 unchecked
<method-permission>
    <unchecked/>
    <method>
        <ejb-name>User</ejb-name>
        <method-name>*</method-name>
    </method>
</method-permission>

该配置仍然安全,因为应用程序 CMP EJB 只提供了本地接口,因此只能从同一 EJB 容器中访问。(该过程从 2005 年 5 月 31 起不在 Geronimo 快照上工作。参阅 参考资料 以链接到 Apache 问题站点,其中提供了有关 JIRA 问题 661 和建议解决方案的详细信息。)

程序性安全

EJB 可以使用 EJBContext.getCallerPrincipal() 方法通过上下文获得调用者主体。但是,在撰写本文时,Geronimo 包含与该功能相关的设计缺陷。Geronimo 返回的 principal 类不包含 Web 容器中可用的所有安全信息。特别地,用户名不能由 principal 对象确定,虽然在 Web 容器中它是可用的。要解决这个问题,示例应用程序在调用 EJB 方法时显式传递用户名。(参阅 参考资料 以链接到 Apache 问题站点,其中提供了有关 JIRA 问题 668 的详细信息。)

结束语

本文描述了如何使用 Geronimo 应用服务器提供的安全设施来构建安全的应用程序。Geronimo 提供了以声明方式和编程方式在不同层次保护应用程序的大量设施。Geronimo 还提供了为中小企业构建安全应用程序的健壮功能。它使用最新标准并依赖 J2EE 规范来提供应用层安全设施。

但是,应用服务器的稳定版本还没有发布;因此,Geronimo 仍包含一些与 J2EE 支持有关的问题。其中一个问题与 EJB 容器有关,它无法确定一些类型的调用者主体信息,比如用户名。此外,值得注意的是,Geronimo 仍缺乏官方参考文档,因此快速查找信息有点困难。但是,因为 Geronimo 是开放源代码的,所以支持文档的缺乏通过开放源代码可用性和用户组支持得到了补偿。

总之,Geronimo 应用服务器具有已经演示的对 J2EE 标准的健壮支持,而且正在中小企业 IT 中寻找用武之地。


相关主题

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文
  • 访问 Apache 站点以查看 Geronimo 文档
  • Geronimo Wiki 提供了有关从源代码编译 Geronimo 的信息。
  • 获取有关 RFC2818 的信息,其中描述了 TLS 之上的 HTTP。
  • 参阅 specification for SSL Version 3
  • 获取有关 RFC 2246 的信息,其中描述了 TLS 规范。
  • 学习 JIRA 问题 661,其中包括详细信息和对未检查权限漏洞的建议解决方案。
  • 学习 JIRA 问题 668,其中包括详细信息和对丢失的安全上下文信息(用户名)的建议解决方案。
  • 查看 Sun 的 keytool 的信息页面,这是一个键和证书管理实用程序。
  • 获得有关 Geronimo 的 GBean 架构的详细信息。
  • 了解 Apache Derby Incubator 项目
  • 阅读有关 Geronimo 的两部分文章系列。第 1 部分“支持 J2EE 1.4 引擎”是对 Geronimo 的简介和概述。第 2 部分“驯服 J2EE 1.4 这匹野马”介绍了 Geronimo 配置、部署、管理,并提供了部署 Web 应用程序和 EJB 的动手操作示例(developerWorks,2005 年 5 月)。
  • 下载 Gluecode Standard Edition,一个免费的基于 Apache Geronimo 的应用服务器。
  • 访问 Geronimo 项目 的官方站点,以访问最新的源代码、二进制文件,以及邮寄列表和 wiki 上的活动社区。
  • 参阅 Apache Geronimo 项目区以从 developerWorks 获得免费的开放源代码的完整清单。
  • 在 developerWorks 开放源代码区域中浏览所有 Apache 文章 和免费的 Apache 教程
  • 访问 developerWorks 开放源代码专区 以获得广泛的技术信息、工具和项目更新,以帮助您用开源技术进行开发,并与 IBM 产品结合使用。
  • 使用 IBM 试用软件 改革您的下一个开源开发项目,该软件可以下载,也可以从 DVD 安装。

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Java technology
ArticleID=91958
ArticleTitle=使用 Geronimo 构建安全的企业基础设施
publish-date=08152005