使用 Acegi 保护 Java 应用程序

第 1 部分: 架构概览和安全过滤器

 

使用 Acegi Security System 实现基于 URL 的安全性

 

 

Acegi Security System 是一种功能强大并易于使用的替代性方案,使您不必再为 Java 企业应用程序编写大量的安全代码。虽然它专门针对使用 Spring 框架编写的应用程序,但是任何类型的 Java 应用程序都没有理由不去使用 Acegi。

 下载 Acegi,这样才能编译本文的示例代码并运行本文的样例应用程序。还必须有作为工作站的一部分运行的 Tomcat 服务器。

 

企业应用程序安全性

 

由于企业内容管理(ECM)应用程序管理存储在不同类型数据源(如文件系统、关系数据库和目录服务)中的企业内容的编写和处理,ECM 安全性要求对这些数据源的访问进行控制。比如,一个 ECM 应用程序可能会控制被授权读取、编辑或删除数据的对象,而这些数据和制造业企业的设计、市场营销、生产以及质量控制有关。

 

在一个 ECM 安全场景中,比较常见的就是通过对企业资源定位符(或网络地址)应用安全性,从而实现访问控制。这种简单的安全模型被称为统一资源定位符 或 URL 安全性。正如我在本文后面(以及本系列后续文章)所演示的一样,Acegi 为实现 URL 安全性提供了全面的特性。

 

然而,在很多企业场景中,URL 安全性还远远不够。比如,假设一个 PDF 文档包含某个制造业公司生产的特殊产品的数据。文档的一部分包含了将由该公司的设计部门编辑和更新的设计数据。另一部分包含了生产经理将使用的生产数据。对于诸如此类的场景,需要实现更加细粒度的安全性,对文档的不同部分应用不同的访问权限。

 

本文介绍了 Acegi 为实现 URL 安全性而提供的各种功能。本系列的下一篇文章将演示此框架的基于方法的安全性,它提供了对企业数据访问的更细粒度的控制。

 

Acegi Security System

 

 

 

Acegi Security System 使用安全过滤器来提供企业应用程序的身份验证和授权服务。该框架提供了不同类型的过滤器,可以根据应用程序的需求进行配置。您将在本文后面了解到 安全过滤器的不同类型;现在,只需注意可以为如下任务配置 Acegi 安全过滤器:

 

  1. 在访问一个安全资源之前提示用户登录。

  2. 通过检查安全标记(如密码),对用户进行身份验证。

  3. 检查经过身份验证的用户是否具有访问某个安全资源的特权。

  4. 将成功进行身份验证和授权的用户重定向到所请求的安全资源。

  5. 对不具备访问安全资源特权的用户显示 Access Denied 页面。

  6. 在服务器上记录成功进行身份验证的用户,并在用户的客户机上设置安全 cookie。使用该 cookie 执行下一次身份验证,而无需要求用户登录。

  7. 将身份验证信息存储在服务器端的会话对象中,从而安全地进行对资源的后续请求。

  8. 在服务器端对象中构建并保存安全信息的缓存,从而优化性能。

  9. 当用户退出时,删除为用户安全会话而保存的服务器端对象。

  10. 与大量后端数据存储服务(如目录服务或关系数据库)进行通信,这些服务用于存储用户的安全信息和 ECM 的访问控制策略。

正如这个列表显示的那样,Acegi 的安全过滤器允许您执行保护企业应用程序所需的几乎任何事情。

 

 

架构和组件

 

对 Acegi 了解越多,使用起来就越简单。这一节介绍 Acegi 的组件;接下来您将了解该框架如何使用反转控制(IOC)和 XML 配置文件来组合组件并表示它们的依赖关系。

 

 

四大组件

Acegi Security System 由四种主要类型的组件组成:过滤器、管理器、提供者和处理程序。

 

过滤器 这种最高级的组件提供了常见的安全服务,如身份验证、会话处理以及注销。我将在 本文后面的部分 深入讨论过滤器。 管理器 过滤器仅是安全相关功能的高级抽象:实际上要使用管理器和提供者实现身份验证处理和注销服务。管理器管理由不同提供者提供的较低级的安全服务。 提供者 有大量的提供者可用于和不同类型的数据存储服务通信,例如目录服务、关系数据库或简单的内存中的对象。这意味着您可以将用户库和访问控制协议存储在任何一种这样的数据存储服务中,并且 Acegi 的管理器将在运行时选择合适的提供者。 处理程序 有时任务可能会被分解为多个步骤,其中每个步骤由一个特定的处理程序执行。比方说,Acegi 的 注销过滤器 使用两个处理程序来退出一个 HTTP 客户机。其中一个处理程序使用户的 HTTP 会话无效,而另一个处理程序则删除用户的 cookie。当根据应用程序需求配置 Acegi 时,多个处理程序能够提供很好的灵活性。您可以使用自己选择的处理程序来执行保护应用程序所需的步骤。

 

反转控制

Acegi 的组件通过彼此之间的依赖来对企业应用程序进行保护。比如,一个身份验证处理过滤器需要一个身份验证管理器选择一个合适的身份验证提供者。这就是说您必须能够表示和管理 Acegi 组件的依赖关系。

 

 

IOC 实现通常用于管理 Java 组件之间的依赖关系。IOC 提供了两个重要的特性:

  1. 它提供了一种语法,表示应用程序所需的组件以及这些组件如何相互依赖。

  2. 它保证了所需的组件在运行时是可用的。

XML 配置文件

Acegi 使用 Spring 框架(请参见 参考资料)附带的流行开源 IOC 实现来管理其组件。Spring 需要您编写一个 XML 配置文件来表示组件的依赖关系,如清单 1 所示:

 

清单 1. Spring 配置文件的结构

                
<beans>
    <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value> value here </value>
        </property>
    </bean>

    <bean id="authenticationProcessingFilter"
        class="org.acegisecurity.ui.webapp.AuthenticationProcessingFitler">
        <property name="authenticationManager" ref="authManager"/>
        <!-- Other properties -->
    </bean>

    <bean id="authManager"
        class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <!--  List of providers here -->
        </property>
    </bean>
    <!-- Other bean tags -->
</beans>

如您所见,Acegi 使用的 Spring XML 配置文件包含一个 <beans> 标记,它封装了一些其他的 <bean> 标记。所有的 Acegi 组件(即过滤器、管理器、提供者等)实际上都是 JavaBean。XML 配置文件中的每个 <bean> 标记都代表一个 Acegi 组件。

 

 

进一步解释 XML 配置文件

首先将注意到的是每个 <bean> 标记都包含一个 class 属性,这个属性标识组件所使用的类。<bean> 标记还具有一个 id 属性,它标识作为 Acegi 组件工作的实例(Java 对象)。

 

 

比方说,清单 1 的第一个 <bean> 标记标识了名为 filterChainProxy 的组件实例,它是名为 org.acegisecurity.util.FilterChainProxy 的类的实例。

 

使用 <bean> 标记的子标记来表示 bean 的依赖关系。比如,注意第一个 <bean> 标记的 <property> 子标记。<property> 子标记定义了 <bean> 标记依赖的其他 bean 或值。

 

所以在 清单 1 中,第一个 <bean> 标记的 <property> 子标记具有一个 name 属性和一个 <value> 子标记,分别定义了这个 bean 依赖的属性的名称和值。

 

同样,清单 1 中的第二个和第三个 <bean> 标记定义了一个过滤器 bean 依赖于一个管理器 bean。第二个 <bean> 标记表示过滤器 bean,而第三个 <bean> 标记表示管理器 bean。

 

过滤器的 <bean> 标记包含一个 <property> 子标记,该子标记具有两个属性:namerefname 属性定义了过滤器 bean 的属性,而 ref 属性引用了管理器 bean 的实例(名称)。

 

下一节将展示如何在 XML 配置文件中配置 Acegi 过滤器。在本文后面的内容中,您将在一个样例 Acegi 应用程序中使用过滤器。

 

 

安全过滤器

 

 

正如我前面提到的一样,Acegi 使用安全过滤器为企业应用程序提供身份验证和授权服务。您可以根据应用程序的需要使用和配置不同类型的过滤器。这一节将介绍五种最重要的 Acegi 安全过滤器。

 

Session Integration Filter

Acegi 的 Session Integration Filter(SIF)通常是您将要配置的第一个过滤器。SIF 创建了一个安全上下文对象,这是一个与安全相关的信息的占位符。其他 Acegi 过滤器将安全信息保存在安全上下文中,也会使用安全上下文中可用的安全信息。

SIF 创建安全上下文并调用过滤器链中的其他过滤器。然后其他过滤器检索安全上下文并对其进行更改。比如,Authentication Processing Filter(我将稍后进行介绍)将用户信息(如用户名、密码和电子邮件地址)存储在安全上下文中。

当所有的处理程序完成处理后,SIF 检查安全上下文是否更新。如果任何一个过滤器对安全上下文做出了更改,SIF 将把更改保存到服务器端的会话对象中。如果安全上下文中没有发现任何更改,那么 SIF 将删除它。

 

在 XML 配置文件中对 SIF 进行了配置,如清单 2 所示:


清单 2. 配置 SIF
                
<bean id="httpSessionContextIntegrationFilter"        
     class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>

 

 

 

Authentication Processing Filter

Acegi 使用 Authentication Processing Filter(APF)进行身份验证。APF 使用一个身份验证(或登录)表单,用户在其中输入用户名和密码,并触发身份验证。

APF 执行所有的后端身份验证处理任务,比如从客户机请求中提取用户名和密码,从后端用户库中读取用户参数,以及使用这些信息对用户进行身份验证。

在配置 APF 时,您必须提供如下参数:

  • Authentication manager 指定了用来管理身份验证提供者的身份验证管理器。

  • Filter processes URL 指定了客户在登录窗口中按下 Sign In 按钮时要访问的 URL。收到这个 URL 的请求后,Acegi 立即调用 APF。

  • Default target URL 指定了成功进行身份验证和授权后呈现给用户的页面。

  • Authentication failure URL 指定了身份验证失败情况下用户看到的页面。

APF 从用户的请求对象中得到用户名、密码和其他信息。它将这些信息传送给身份验证管理器。身份验证管理器使用适当的提供者从后端用户库中读取详细的用户信息(如用户名、密码、电子邮件地址和用户访问权利或特权),对用户进行身份验证,并将信息存储在一个 Authentication 对象中。

最后,APF 将 Authentication 对象保存在 SIF 之前创建的安全上下文中。存储在安全上下文中的 Authentication 对象将用于做出授权决策。

APF 的配置如清单 3 所示:


清单 3. 配置 APF

                
<bean id="authenticationProcessingFilter"
    class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
    <property name="authenticationManager"
        ref="authenticationManager" />
    <property name="filterProcessesUrl"
        value="/j_acegi_security_check" />
    <property name="defaultTargetUrl"
        value="/protected/protected1.jsp" />
    <property name="authenticationFailureUrl"
        value="/login.jsp?login_error=1" />
</bean>

可以从这段代码中看到,APF 依赖于上面讨论的这四个参数。每个参数都是作为清单 3 所示的 <property> 标记配置的。

 

 

Logout Processing Filter

Acegi 使用一个 Logout Processing Filer(LPF)管理注销处理。当客户机发来注销请求时,将使用 LPF 进行处理。它标识了来自由客户机所调用 URL 的注销请求。

LPF 的配置如清单 4 所示:


清单 4. 配置 LPF

                
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
    <constructor-arg value="/logoutSuccess.jsp"/>
    <constructor-arg>
        <list>
            <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
</bean>

可以看到 LPF 在其构造方法中包含两个参数:注销成功 URL(/logoutSuccess.jsp)和处理程序列表。注销成功 URL 用来在注销过程完成后重定向客户机。处理程序执行实际的注销过程;我在这里只配置了一个处理程序,因为只需一个处理程序就可以使 HTTP 会话变为无效。我将在本系列下一篇文章中讨论更多的处理程序。

 

 

 

待续!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值