首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

运用 Acegi 保护 Java 应用程序: 续一

2012-10-27 
使用 Acegi 保护 Java 应用程序: 续一使用 Acegi 保护 Java 应用程序: 续一 ?正如清单 5 所示,ETF 包含两

使用 Acegi 保护 Java 应用程序: 续一
使用 Acegi 保护 Java 应用程序: 续一

?


正如清单 5 所示,ETF 包含两个参数,名为 authenticationEntryPoint 和 accessDeniedHandler。authenticationEntryPoint 属性指定登录页面,而 accessDeniedHandler 指定 Access Denied 页面。

?

?

如清单 7 所示,配置所需的三个组件是 authenticationManager、accessDecisionManager、objectDefinitionSource:

authenticationManager 组件与我在介绍 Authentication Processing Filter 时讨论过的身份验证管理器相同。拦截过滤器可以在授权的过程中使用 authenticationManager 重新对客户机进行身份验证。

accessDecisionManager 组件管理授权过程,这部分内容将在本系列的下篇文章中详细讨论。

objectDefinitionSource 组件包含对应于将要发生的授权的访问控制定义。例如,清单 7 中的 objectDefinitionSource 属性值包含两个 URL(/protected/* 和 /*)。其值定义了这些 URL 的角色。/protected/* URL 的角色是 ROLE_HEAD_OF_ENGINEERING。您可以根据应用程序的需要定义任何角色。

回想一下 清单 6,您为用户名 alice 定义了 ROLE_HEAD_OF_ENGINEERING。这就是说 alice 将能够访问 /protected/* URL。

?

?

下面的步骤描述了过滤器链的生命周期:

    浏览器客户机向您的应用程序发送 HTTP 请求。

    容器接收到 HTTP 请求并创建一个请求对象,该对象将封装 HTTP 请求中包含的信息。容器还创建一个各种过滤器都可处理的响应对象,从而为发出请求的客户机准备好 HTTP 响应。容器然后调用 Acegi 的过滤器链代理,这是一个代理过滤器。该代理知道应用的过滤器的实际顺序。当容器调用代理时,它将向代理发送请求、响应以及过滤器链对象。

    代理过滤器调用过滤器链中第一个过滤器,向其发送请求、响应和过滤器链对象。

    链中的过滤器逐个执行其处理。一个过滤器可以通过调用过滤器链中下一个过滤器随时终止自身处理。有的过滤器甚至根本不执行任何处理(比如,如果 APF 发现一个到来的请求没有要求身份验证,它可能会立即终止其处理)。

    当身份验证过滤器完成其处理时,这些过滤器将把请求和响应对象发送到应用程序中配置的拦截过滤器。

    拦截器决定是否对发出请求的客户机进行授权,使它访问所请求的资源。

    拦截器将控制权传输给应用程序(比如,成功进行了身份验证和授权的客户机请求的 JSP 页面)。

    应用程序改写响应对象的内容。

    响应对象已经准备好了,容器将响应对象转换为 HTTP 响应,并将响应发送到发出请求的客户机。

为帮助您进一步理解 Acegi 过滤器,我将详细探讨其中两个过滤器的操作:Session Integration Filter 和 Authentication Processing Filter。

?

?

现在详细地考虑下面这些步骤:

    Acegi 的过滤器链代理调用 SIF 并向其发送请求、响应和过滤器链对象。注意:通常将 SIF 配置为过滤器链中第一个过滤器。

    SIF 检查它是否已经对这个 Web 请求进行过处理。如果是的话,它将不再进一步进行处理,并将控制权传输给过滤器链中的下一个过滤器(参见下面的第 4 个步骤)。如果 SIF 发现这是第一次对这个 Web 请求调用 SIF,它将设置一个标记,将在下一次使用该标记,以表示曾经调用过 SIF。

    SIF 将检查是否存在一个会话对象,以及它是否包含安全上下文。它从会话对象中检索安全上下文,并将其放置在名为 security context holder 的临时占位符中。如果不存在会话对象,SIF 将创建一个新的安全上下文,并将它放到 security context holder 中。注意:security context holder 位于应用程序的范围内,所以可以被其他的安全过滤器访问。

    SIF 调用过滤器链中的下一个过滤器。

    其他过滤器可以编辑安全上下文。

    SIF 在过滤器链完成处理后接收控制权。

    SIF 检查其他的过滤器是否在其处理过程中更改了安全上下文(比如,APF 可能将用户详细信息存储在安全上下文中)。如果是的话,它将更新会话对象中的安全上下文。就是说在过滤器链处理过程中,对安全上下文的任何更改现在都保存在会话对象中。

现在仔细考虑以下这些步骤:

    过滤器链中前面的过滤器向 APF 发送请求、响应和过滤链对象。

    APF 使用从请求对象中获得的用户名、密码以及其他信息创建身份验证标记。

    APF 将身份验证标记传递给身份验证管理器。

    身份验证管理器可能包含一个或更多身份验证提供者。每个提供者恰好支持一种类型的身份验证。管理器检查哪一种提供者支持它从 APF 收到的身份验证标记。

    身份验证管理器将身份验证标记发送到适合进行身份验证的提供者。

    身份验证提供者支持从身份验证标记中提取用户名,并将它发送给名为 user cache service 的服务。Acegi 缓存了已经进行过身份验证的用户。该用户下次登录时,Acegi 可以从缓存中加载他或她的详细信息(比如用户名、密码和权限),而不是从后端数据存储中读取数据。这种方法使得性能得到了改善。

    user cache service 检查用户的详细信息是否存在于缓存中。

    user cache service 将用户的详细信息返回给身份验证提供者。如果缓存不包含用户详细信息,则返回 null。

    身份验证提供者检查缓存服务返回的是用户的详细信息还是 null。

    如果缓存返回 null,身份验证提供者将用户名(在步骤 6 中提取)发送给另一个名为 user details service 的服务。

    user details service 与包含用户详细信息的后端数据存储通信(如目录服务)。

    user details service 返回用户的详细信息,或者,如果找不到用户详细信息则抛出身份验证异常。

    如果 user cache service 或者 user details service 返回有效的用户详细信息,身份验证提供者将使用 user cache service 或 user details service 返回的密码来匹配用户提供的安全标记(如密码)。如果找到一个匹配,身份验证提供者将用户的详细信息返回给身份验证管理器。否则的话,则抛出一个身份验证异常。

    身份验证管理器将用户的详细信息返回给 APF。这样用户就成功地进行了身份验证。

    APF 将用户详细信息保存在 图 2 所示由步骤 3 创建的安全上下文中。

    APF 将控制权传输给过滤器链中的下一个过滤器。

一个简单的 Acegi 应用程序见附件,注意:需要加入一些jar包(acegi,spring),才可以运行。

热点排行