ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品亚洲片夜色在线,欧美美女搞黄,欧美一级大片在线视频http://www.aygfsteel.com/waterjava/category/31364.html我胡汉山又回来了!zh-cnThu, 08 May 2008 12:53:09 GMTThu, 08 May 2008 12:53:09 GMT60acegi,IBMçš„Acegi Security SystemåQ?åQ?http://www.aygfsteel.com/waterjava/archive/2008/05/08/199314.html狼爱上狸狼爱上狸Thu, 08 May 2008 10:50:00 GMThttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199314.htmlhttp://www.aygfsteel.com/waterjava/comments/199314.htmlhttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199314.html#Feedback0http://www.aygfsteel.com/waterjava/comments/commentRss/199314.htmlhttp://www.aygfsteel.com/waterjava/services/trackbacks/199314.html2008 òq?3 æœ?20 æ—?/p>
Bilal Siddiqui ž®†ç‘ô¾l­åœ¨ä»–çš„ ¾pÕdˆ—文章 中展½Cºå¦‚何ä‹Éç”?Acegi 保护 Java™Server Faces (JSF) 应用½E‹åºã€‚配¾|?JSF å’?AcegiåQŒè®©å®ƒä»¬åœ?servlet 容器中协作,探烦 JSF å’?Acegi ¾l„äšg如何彼此协作ã€?/blockquote>

æœ?¾pÕdˆ— 的前 3 部分讨论了如何ä‹Éç”?Acegi Security System 保护 Java 企业应用½E‹åºåQ?/p>

  • ½W?1 部分 解释了如何ä‹Éç”?Acegi 的内¾|®è¿‡æ»¤å™¨å®žçŽ°ä¸€ä¸ªç®€å•çš„åŸÞZºŽ URL 的安全系¾lŸã€?
  • ½W?2 部分 展示了如何编写访问控制策略、将其存储在 LDAP 目录服务器中åQŒä»¥åŠé…¾|?Acegi ä¸?LDAP 服务器交互,从而实现访问控制策略ã€?
  • ½W?3 部分 展示了如何在企业应用½E‹åºä¸­ä‹Éç”?Acegi 保护å¯?Java ¾cÕd®žä¾‹çš„讉K—®ã€?

½W?4 部分ž®†è®¨è®ºå¦‚何ä‹Éç”?Acegi 保护åœ?servlet 容器中运行的 JavaServer Faces (JSF) 应用½E‹åºã€‚本文首先解é‡?Acegi 针对此目标提供的ç‰ÒŽ€§ï¼Œòq¶æ¾„清一些关于ä‹Éç”?Acegi å’?JSF 的常见误解。然后提供一个简单的 web.xml æ–‡äšgåQŒå¯ä»¥ç”¨æ¥éƒ¨¾|?AcegiåQŒä»Žè€Œä¿æŠ?JSF 应用½E‹åºã€‚然后深入探è®?Acegi å’?JSF ¾l„äšgåQŒäº†è§£åœ¨éƒ¨çÖv web.xml æ–‡äšg和用戯‚®¿é—?JSF 应用½E‹åºæ—¶æ‰€å‘生的事件。本文最后提供了一个由 Acegi 保护的示ä¾?JSF 应用½E‹åºã€?

无需¾~–写 Java 代码卛_¯æ·ÕdР安免æ€?/span>

回顾一下本¾pÕdˆ—的第一个示ä¾?Acegi 应用½E‹åºåQˆè¯·å‚阅 ½W?1 部分 中的 “一个简å?Acegi 应用½E‹åº” 一节)。该应用½E‹åºä½¿ç”¨ Acegi 提供了以下安全特性:

  • 当一个未¾léªŒè¯çš„用户试图讉K—®å—保护的资源æ—Óž¼Œæä¾›ä¸€ä¸ªç™»å½•页面ã€?
  • ž®†æŽˆæƒç”¨æˆïL›´æŽ¥é‡å®šå‘到所需的受保护资源ã€?
  • 如果用户未被授权讉K—®å—保护资源,提供一个访问拒¾lé¡µé¢ã€?

回想一下,您无需¾~–写ä»ÖM½• Java 代码ž®Þpƒ½èŽ·å¾—˜q™äº›ç‰ÒŽ€§ã€‚只需要对 Acegi ˜q›è¡Œé…ç½®ã€‚åŒæ øP¼Œåœ?JSF 应用½E‹åºä¸­ï¼Œæ— éœ€¾~–写ä»ÖM½• Java 代码åQŒä¹Ÿåº”该能够ä»?Acegi 实现相同的特性ã€?/p>

澄清误解

其他一些作者似乎认为将 Acegi ä¸?JSF 集成需è¦?JSF 应用½E‹åºæä¾›ç™Õd½•™åµé¢åQˆå‚è§?参考资æ–?/a>åQ‰ã€‚è¿™¿Uè§‚ç‚¹åÆˆä¸æ­£¼‹®ã€‚在需要时提供ç™Õd½•™åµé¢åQŒè¿™æ˜?Acegi 的职责。确保登录页面在安全会话期间只出çŽîC¸€‹Æ¡ï¼Œ˜q™ä¹Ÿæ˜?Acegi 的职责。然后,¾lè¿‡íw«ä†¾éªŒè¯å’ŒæŽˆæƒçš„用户可以讉K—®ä¸€ä¸ªå—保护资源åQŒæ— éœ€é‡å¤æ‰§è¡Œç™Õd½•˜q‡ç¨‹ã€?/p>

如果使用 JSF 提供ç™Õd½•™åµé¢åQŒå°†ä¼šå‘生两个主要的问题åQ?/p>

Acegi 的目的是避免¾~–写 Java 安全代码。如果ä‹Éç”?JSF 提供ç™Õd½•™åµé¢åQŒåˆ™æ²¡æœ‰å®žçް˜q™ä¸€ç”¨é€”,òq¶ä¸”会引发一¾pÕdˆ—å…¶ä»– JSF-Acegi 集成问题åQŒæ‰€æœ‰è¿™äº›é—®é¢˜éƒ½æºäºŽ “Acegi 是用来提供可配置安全æ€?#8221; ˜q™ä¸€äº‹å®žã€‚如果试图ä‹Éç”?JSF 来完æˆ?Acegi 的工作,ž®†ä¼šé‡åˆ°éºÈƒ¦ã€?/p>

本文余下部分ž®†è§£é‡Šåƈ演示独立äº?Acegi çš?JSF 应用½E‹åºå¼€å‘,òq¶åœ¨½EåŽé…ç½® Acegi 以保æŠ?JSF 应用½E‹åº â€?无需¾~–写ä»ÖM½• Java 代码。首先看一ä¸?web.xml æ–‡äšgåQŒå¯ä»¥éƒ¨¾|²è¯¥æ–‡äšg保护 JSF 应用½E‹åºã€?/p>



回页�/strong>


部çÖv Acegi 保护 JSF 应用½E‹åº

清单 1 展示了一ä¸?web.xml æ–‡äšgåQˆé€šå¸¸¿UîCؓ部çÖv描述½W?/em>åQ‰ï¼Œå¯ä»¥ä½¿ç”¨˜q™ä¸ªæ–‡äšg部çÖv AcegiåQŒä»Žè€Œä¿æŠ¤è¿è¡Œåœ¨ servlet 容器åQˆæ¯”å¦?Apache TomcatåQ‰ä¸­çš?JSF 应用½E‹åºåQ?/p>
清单 1. 用于部çÖv Acegi å’?servlet 容器中的 JSF çš?web.xml æ–‡äšg
                        <?xml version="1.0"?>
            <!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd">
            <web-app>
            <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/acegi-config.xml</param-value>
            </context-param>
            <context-param>
            <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
            <param-value>server</param-value>
            </context-param>
            <context-param>
            <param-name>javax.faces.CONFIG_FILES</param-name>
            <param-value>/WEB-INF/faces-config.xml</param-value>
            </context-param>
            <listener>
            <listener-class>
            org.springframework.web.context.ContextLoaderListener
            </listener-class>
            </listener>
            <listener>
            <listener-class>
            com.sun.faces.config.ConfigureListener
            </listener-class>
            </listener>
            <!-- Faces Servlet -->
            <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup> 1 </load-on-startup>
            </servlet>
            <!-- Faces Servlet Mapping -->
            <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.faces</url-pattern>
            </servlet-mapping>
            <!-- Acegi filter configuration -->
            <filter>
            <filter-name>Acegi Filter Chain Proxy</filter-name>
            <filter-class>
            org.acegisecurity.util.FilterToBeanProxy
            </filter-class>
            <init-param>
            <param-name>targetClass</param-name>
            <param-value>
            org.acegisecurity.util.FilterChainProxy
            </param-value>
            </init-param>
            </filter>
            <!-- Acegi Filter Mapping -->
            <filter-mapping>
            <filter-name>Acegi Filter Chain Proxy</filter-name>
            <url-pattern>/*</url-pattern>
            </filter-mapping>
            </web-app>
            

注意åQ?a cmimpressionsent="1">清单 1 包含以下标记åQ?/p>

  • 3 ä¸?<context-param> 标记
  • 2 ä¸?<listener> 标记
  • 1 ä¸?<filter> 标记
  • 1 ä¸?<servlet> 标记
  • 1 ä¸?<servlet-mapping> 标记
  • 1 ä¸?<filter-mapping> 标记

阅读该文ä»Óž¼Œäº†è§£æ¯ä¸ªæ ‡è®°åœ?JSF-Acegi 应用½E‹åºä¸­çš„用途ã€?/p>

�Acegi �JSF 提供上下文参�/span>

清单 1 中的每个 <context-param> 标记定义一个参敎ͼŒä¾?Acegi æˆ?JSF 在启动或执行期间使用。第一个参æ•?â€?contextConfigLocation â€?定义 Acegi çš?XML 配置文äšg的位¾|®ã€?/p>

JSF 需è¦?javax.faces.STATE_SAVING_METHOD å’?javax.faces.CONFIG_FILES 参数ã€?code>javax.faces.STATE_SAVING_METHOD 参数指定希望在客æˆähœº˜q˜æ˜¯æœåŠ¡å™¨ä¸Šå­˜å‚¨ JSF ™åµé¢-视图状态。Sun çš„å‚è€ƒå®žçŽ°çš„é»˜è®¤è¡ŒäØ“æ˜¯å°† JSF 视图存储在服务器上ã€?/p>

javax.faces.CONFIG_FILES 参数指定 JSF 需要的配置文äšg的位¾|®ã€‚JSF 配置文äšg的详¾l†ä¿¡æ¯ä¸å±žäºŽæœ¬æ–‡è®¨è®ºçš„范å›ß_¼ˆå‚见 参考资æ–?/a>åQŒèŽ·å–æ¶‰åŠè¯¥ä¸»é¢˜çš„èµ„æºé“¾æŽ¥ï¼‰ã€?/p>

�Acegi �JSF 配置侦听�/span>

现在看一ä¸?清单 1 中的 2 ä¸?<listener> 标记ã€?code><listener> 标记定义侦听器类åQŒä¾¦å¬å™¨¾cÖM¾¦å¬åƈ处理 JSP æˆ?servlet 应用½E‹åºå¯åŠ¨å’Œæ‰§è¡ŒæœŸé—´å‘ç”Ÿçš„äº‹äšg。例如:

  • 启动 JSP æˆ?servlet 应用½E‹åºæ—Óž¼Œservlet 容器创徏一个新çš?servlet 上下文。每å½?JSP æˆ?servlet 应用½E‹åºå¯åЍæ—Óž¼Œž®×ƒ¼šè§¦å‘此事件ã€?br />
  • servlet 容器创徏一个新çš?servlet è¯äh±‚对象。每当容器从客户机收åˆîC¸€ä¸?HTTP è¯äh±‚æ—Óž¼Œæ­¤äº‹ä»¶å°±ä¼šå‘生ã€?

  • 建立一个新çš?HTTP 会话。当è¯äh±‚客户机徏立一个与 servlet 容器的会话时åQŒæ­¤äº‹äšgž®×ƒ¼šå‘生ã€?

  • 一个新属性被æ·ÕdŠ åˆ?servlet 上下文、servlet è¯äh±‚å’?HTTP 会话对象ã€?br />
  • servlet 上下文、servlet è¯äh±‚æˆ?HTTP 会话对象的一个现有属性被修改或删除ã€?

<listener> 标记ž®±åƒä¸€¿Uå¯æ‰©å±•性机åˆÓž¼Œå…è®¸åœ?servlet 容器内部˜qè¡Œçš„应用程序协同某些事件进行处理。servlet 规范定义了侦听器¾cÖMؓ处理事äšg而实现的一些接口ã€?/p>

例如åQŒSpring Framework 实现一ä¸?javax.servlet.ServletContextListener servlet 接口。实现此接口çš?spring ¾cÀL˜¯ org.springframework.web.context.ContextLoaderListener。注意,˜q™æ˜¯ 清单 1 的第一ä¸?<listener> 标记中的侦听器类ã€?

¾cÖM¼¼åœŽÍ¼ŒJSF 实现一ä¸?com.sun.faces.config.ConfigureListener ¾c»ï¼Œè¯¥ç±»å®žçŽ°ä¸€äº›äº‹ä»?侦听接口。可以在 清单 1 的第二个 <listener> 标记中找åˆ?ConfigureListener ¾c…R€?/p>

本文½EåŽž®†è§£é‡Šä¸åŒçš„事äšg-侦听器接口,以及 Acegi å’?JSF 事äšg-侦听器类内部执行的处理(请参é˜?“启动 JSF-Acegi 应用½E‹åº” å’?“处理对受 Acegi 保护çš?JSF ™åµé¢çš„请æ±?/a>”åQ‰ã€?/p>

配置和映ž®?servlet ˜q‡æ×oå™?/span>

现在看一ä¸?清单 1 中的 <filter> 标记。在è¯äh±‚çš?servlet 处理传入的请求之前,servlet 应用½E‹åºä½¿ç”¨˜q‡æ×o器对其进行预处理。在è¯äh±‚执行之前åQŒAcegi 使用 servlet ˜q‡æ×o器对用户˜q›è¡Œíw«ä†¾éªŒè¯ã€?/p>

è¯äh³¨æ„?清单 1 中的 <filter> 标记åQŒå®ƒçš?<filter-class> 子标记指定一ä¸?org.acegisecurity.util.FilterToBeanProxy ¾c…R€?code>FilterToBeanProxy ¾cÀL˜¯ Acegi 的一部分。此¾cÕd®žçŽîC¸€ä¸?javax.servlet.Filter 接口åQŒè¯¥æŽ¥å£æ˜?servlet 应用½E‹åºçš„一部分ã€?code>javax.servlet.Filter 接口有一ä¸?doFilter() æ–ÒŽ³•åQŒservlet 容器在收到请求时调用该方法ã€?/p>

˜q˜éœ€æ³¨æ„åQ?a cmimpressionsent="1">清单 1 çš?<filter> 标记有另一个子标记 <init-param>ã€?code><init-param> 标记指定实例åŒ?FilterToBeanProxy ¾cÀL‰€éœ€çš„参数。可以从 清单 1 中看出,FilterToBeanProxy ¾cÕdªéœ€è¦ä¸€ä¸ªå‚敎ͼŒè¯¥å‚数是 FilterChainProxy ¾cȝš„一个对象ã€?code>FilterChainProxy ¾c»è¡¨½C?½W?1 部分 1 中讨论的整个 Acegi ˜q‡æ×o器链åQˆè¯·å‚阅 “安全˜q‡æ×oå™?#8221; ž®èŠ‚åQ‰ã€?code>FilterToBeanProxy ¾cȝš„ doFilter() æ–ÒŽ³•使用 FilterChainProxy ¾cÀL‰§è¡?Acegi 的安全过滤器链ã€?/p>

清单 1 中的 <filter-mapping> 标记指定调用 Acegi çš?FilterToBeanProxy 的请æ±?URL。我已经ž®†æ‰€æœ‰çš„ JSF ™åµé¢æ˜ å°„åˆ?Acegi çš?FilterToBeanProxy。这意味着只要用户试图讉K—® JSF ™åµé¢åQ?code>FilterChainProxy doFilter() æ–ÒŽ³•ž®×ƒ¼šè‡ªåŠ¨èŽ·å¾—æŽ§åˆ¶æƒã€?/p>

配置 JSF servlet

web.xml æ–‡äšg中的 <servlet> 标记指定希望从特å®?URl 调用çš?servletåQˆåœ¨æœ¬ä¾‹ä¸­æ˜¯ä¸€ä¸?JSF servletåQ‰ã€?code><servlet-mapping> 标记定义è¯?URL。几乎所有的 JSP æˆ?servlet 应用½E‹åºéƒ½åŒ…含这两个标记åQŒæ‰€ä»¥æ— éœ€å†ä½œè®¨è®ºåQˆå‚è§?参考资æ–?/a>åQŒèŽ·å–è®¨è®?servlet ¾~–程的资源链接)ã€?/p>

现在åQŒæ‚¨å·²ç»çœ‹åˆ°åQŒweb.xml æ–‡äšg要部¾|?Acegi 以保æŠ?JSF 应用½E‹åºæ‰€éœ€çš„æ‰€æœ‰æ ‡è®°ã€‚您已经了解了侦听器、过滤器å’?servlet å¦‚ä½•ç›æ€º’协作。从˜q™é‡Œçš„讨è®ÞZ¸­å¯ä»¥çœ‹å‡ºåQŒå¦‚果在 servlet 容器中部¾|?清单 1 中的 web.xml æ–‡äšgåQŒAcegi å’?JSF 都试囑֜¨ä¸¤ç§æƒ…åŞ下进行一些处理:

  • 当启动应用程序时
  • 当应用程序收到对 JSF ™åµé¢çš„请求时

接下来的两节解释每种情况中发生的一¾pÕdˆ—事äšgã€?





回页�/strong>


启动 JSF-Acegi 应用½E‹åº

å›?1 展示了在 JSF-Acegi 应用½E‹åºå¯åŠ¨æ—¶å‘ç”Ÿçš„äº‹äšg™åºåºåQ?/p>
å›?1. JSF-Acegi 应用½E‹åºå¯åŠ¨æ—¶å‘ç”Ÿçš„äº‹äšg™åºåº
JSF-Acegi 应用½E‹åºå¯åŠ¨æ—¶å‘ç”Ÿçš„äº‹äšg™åºåº


详细来讲åQ?a cmimpressionsent="1">å›?1 昄¡¤ºçš„事仉™¡ºåºå¦‚下所½Cºï¼š

  1. servlet 容器实例化在 web.xml æ–‡äšg中配¾|®çš„æ‰€æœ‰ä¾¦å¬å™¨ã€?br />
  2. servlet 容器ž®?Acegi çš?ContextLoaderListener 注册ä¸ÞZ¸€ä¸ªä¾¦å¬å™¨¾c»ï¼Œè¯¥ç±»å®žçް javax.servlet.ServletContextListener接口ã€?code>ServletContextListener 接口包含两个重要æ–ÒŽ³•åQ?code>contextInitialized() å’?contextDestroyed()åQ?
    • contextInitialized() æ–ÒŽ³•在初始化 servlet 上下文时获得控制权ã€?
    • ¾cÖM¼¼åœŽÍ¼Œå½“应用程序退出时åQ?code>contextDestroyed() æ–ÒŽ³•会被调用åQŒåƈ消除 servlet 上下文ã€?

  3. servlet 容器ž®?JSF çš?ConfigureListener 注册为另一个侦听器。JSF çš?ConfigureListener 实现许多侦听器接口,比如 ServletContextListenerã€?ServletContextAttributeListenerã€?ServletRequestListeneråQŒä»¥å?ServletRequestAttributeListener。您已经看到äº?ServletContextListener 接口的方法。余下的接口是:
  4. servlet 容器创徏一ä¸?servlet 上下文对è±?/em>åQŒè¯¥å¯¹è±¡ž®è£…应用½E‹åºèµ„源åQˆæ¯”å¦?JSP ™åµé¢ã€Java ¾cÕd’Œåº”用½E‹åºåˆå§‹åŒ–参敎ͼ‰åQŒåƈ允许整个应用½E‹åºè®‰K—®˜q™äº›èµ„源。JSF-Acegi 应用½E‹åºçš„æ‰€æœ‰å…¶ä»–组ä»Óž¼ˆä¾¦å¬å™¨ã€è¿‡æ»¤å™¨åQŒä»¥å?servletåQ‰åœ¨ servlet 上下文对象中以属性的形式存储与应用程序资源相关的信息ã€?br />
  5. servlet 容器通知 Acegi çš?ContextLoaderListeneråQŒservlet 上下文是通过调用 ContextLoaderListener çš?contextInitializated() æ–ÒŽ³•初始化的ã€?br />
  6. contextInitialized() æ–ÒŽ³•解析 Acegi 的配¾|®æ–‡ä»Óž¼Œä¸?JSF-Acegi 应用½E‹åºåˆ›å¾ Web 应用½E‹åºä¸Šä¸‹æ–‡ï¼Œä»¥åŠå®žä¾‹åŒ–所有的安全˜q‡æ×o器和åœ?Acegi 配置文äšg中配¾|®çš„ Jave bean。在以后 JSF 应用½E‹åºæ”¶åˆ°æ¥è‡ªå®¢æˆ·æœºçš„è¯äh±‚æ—Óž¼Œ˜q™äº›˜q‡æ×o器对象将会用于èín份验证和授权åQˆå‚é˜?½W?3 部分 中关äº?Web 应用½E‹åºä¸Šä¸‹æ–‡åˆ›å»ºçš„讨论和图 1åQ‰ã€?

  7. servlet 容器通知 JSF çš?ConfigureListeneråQŒservlet 上下文是通过调用 contextInitialized() æ–ÒŽ³•初始化的ã€?br />
  8. contextInitialized() æ–ÒŽ³•‹‚€æŸ¥åœ¨ JSF 配置文äšg中配¾|®çš„æ‰€æœ?JSF 托管 beanåQŒç¡®ä¿?Java ¾cÖM¸Žæ¯ä¸ª bean òq¶å­˜ã€?br />
  9. servlet 容器‹‚€æŸ?web.xml æ–‡äšg中ä“Q何配¾|®çš„˜q‡æ×o器。例如,清单 1 中的 web.xml æ–‡äšg包含一ä¸?Acegi ˜q‡æ×oå™?FilterToBeanProxyåQŒservlet 容器ž®†å…¶å®žä¾‹åŒ–、初始化òq¶æ³¨å†Œäؓ一个过滤器。Acegi 现在可以对传入的è¯äh±‚执行íw«ä†¾éªŒè¯å’ŒæŽˆæƒäº†ã€?

  10. servlet 容器实例åŒ?faces servletåQŒåŽè€…开始侦听从用户传入的请求ã€?

下一节解é‡?JSF-Acegi 应用½E‹åºæ”¶åˆ°æ¥è‡ªç”¨æˆ·çš„请求时发生的一¾pÕdˆ—事äšgã€?/p>



回页�/strong>


处理对受 Acegi 保护çš?JSF ™åµé¢çš„请æ±?/span>

您已¾läº†è§£äº†å¦‚何配置 Acegi 保护 JSF 应用½E‹åºã€‚也看到了当启动 JSF-Acegi 应用½E‹åºæ—¶å‘生的一¾pÕdˆ—事äšg。本节描˜q°å½“用户发送一个对å?Acegi 保护çš?JSF ™åµé¢çš„请求时åQŒJSF å’?Acegi ¾l„äšg如何åœ?servlet 容器的框架中˜qè¡Œã€?/p>

å›?2 展示了当客户机发送一个对å?Acegi 保护çš?JSF ™åµé¢çš„请求时åQŒå‘生的事äšg™åºåºåQ?/p>
å›?2. JSF å’?Acegi 协作提供 JSF ™åµé¢
JSF å’?Acegi 协作提供 JSF ™åµé¢


详细来讲åQ?a cmimpressionsent="1">å›?2 展示的事仉™¡ºåºå¦‚下所½Cºï¼š

  1. servlet 容器创徏一个表½Cºç”¨æˆ¯‚¯·æ±‚çš„ servlet è¯äh±‚对象ã€?br />
  2. 回想一ä¸?启动 JSF-Acegi 应用½E‹åº ž®èŠ‚ä¸­çš„½W?3 步,JSF çš?ConfigureListener 实现 ServletRequestListener 接口。这意味着 ConfigureListener 侦听与创建和删除 servlet è¯äh±‚对象相关的事件。因此,servlet 容器调用 ConfigureListener ¾cȝš„ requestInitialized() æ–ÒŽ³•ã€?br />
  3. requestInitialized() æ–ÒŽ³•准备执行è¯äh±‚çš?JSF 生命周期。准备过½E‹åŒ…括检查请求的 faces 上下文是否存在。faces 上下文封装与应用½E‹åºèµ„源相关的信息。faces servlet 执行 JSF 生命周期旉™œ€è¦è¿™äº›ä¿¡æ¯ã€‚如果此è¯äh±‚是新会话的第一个请求,ž®×ƒ¼š¾~ºå°‘ faces 上下文。在˜q™ç§æƒ…况下,requestInitialized() æ–ÒŽ³•创徏一个新çš?faces 上下文ã€?br />
  4. servlet 容器‹‚€æŸ¥ç”¨æˆïLš„è¯äh±‚是否带有ä»ÖM½•状态信息。如æž?servlet 容器未找到状态信息,它会假设该请求是æ–îC¼šè¯çš„½W¬ä¸€ä¸ªè¯·æ±‚,òq¶äؓ用户创徏一ä¸?HTTP 会话对象。如æž?servlet 容器发现该请求包含某¿UçŠ¶æ€ä¿¡æ¯ï¼ˆæ¯”å¦‚ä¸€ä¸?cookie æˆ?URL 中的某种状态信息)åQŒå®ƒž®×ƒ¼šæ ÒŽ®ä¿å­˜çš„会话信息恢复用户以前的会话ã€?br />
  5. servlet 容器把请æ±?URL 与一ä¸?URL 模式˜q›è¡ŒåŒšw…åQŒè¿™ä¸?URL 模式包含在配¾|®æ˜q°ç¬¦ä¸­çš„ <filter-mapping> 标记çš?<url-pattern> 子标è®îC¸­ã€‚如果请æ±?URL 与这ä¸?URL 模式匚w…åQŒservlet 容器调用 Acegi çš?FilterToBeanProxyåQ?code>FilterToBeanProxy 已在 å›?1 的第 9 æ­¥ä¸­è¢«æ³¨å†ŒäØ“ä¸€ä¸?servlet ˜q‡æ×o器ã€?br />
  6. Acegi çš?FilterToBeanProxy 使用 FilterChainProxy ¾cÀL‰§è¡?Acegi 的完整的安全˜q‡æ×o器链。Acegi 的过滤器自动‹‚€æŸ¥ç¬¬ 4 步中创徏çš?HTTP 会话对象åQŒä»¥æŸ¥çœ‹è¯äh±‚客户机是否已被验证。如æž?Acegi 发现用户未被验证åQŒå®ƒæä¾›ä¸€ä¸ªç™»å½•页面。否则,它就直接执行 ½W?2 部分 çš?“配置拦截å™?#8221; 一节中描述的授权过½E‹ã€?

  7. Acegi 使用¾lè¿‡éªŒè¯çš„用æˆïLš„会话信息更新 servlet 上下文ã€?br />
  8. servlet 容器通知 JSF çš?ConfigureListener çš?attributeReplaced() æ–ÒŽ³•åQŒservlet 上下文已被更新ã€?code>ConfigureListener ‹‚€æŸ¥æ˜¯å¦æœ‰ä»ÖM½• JSF bean 被更攏V€‚如果发çŽîC“Q何更改,它相应地更新 faces 上下文。但是,在本例中åQŒåœ¨íw«ä†¾éªŒè¯˜q‡ç¨‹ä¸?Acegi 没有更改ä»ÖM½• JSF 托管 beanåQŒå› æ­¤åœ¨æ­¤è°ƒç”¨æœŸé—?ConfigureListener 不进行ä“Q何处理ã€?br />
  9. 如果授权˜q‡ç¨‹æˆåŠŸåQŒæŽ§åˆ¶æƒè¢«è{¿UÕdˆ° faces servletåQŒå®ƒæ‰§è¡Œ JSF 生命周期òq¶å‘用户发回一个响应ã€?

现在åQŒæ‚¨äº†è§£äº?JSF å’?Acegi 如何协作提供 JSF è¯äh±‚åQŒæŽ¥ä¸‹æ¥çœ‹ä¸€ä¸‹å®ŒæˆåŽçš?JSF å’?Acegiã€?/p>



回页�/strong>


½CÞZ¾‹ JSF-Acegi 应用½E‹åº

本文的下载部分(参见 下蝲åQ‰åŒ…含一个示ä¾?JSF-Acegi 应用½E‹åº JSFAcegiSampleåQŒæ¼”½CÞZº† Acegi ä¸?JSF 的简单集成。示例应用程序ä‹Éç”?清单 1 中的 web.xmlã€?

要部¾|²ç¤ºä¾‹åº”用程序,执行 ½W?1 部分 çš?“部çÖvòq¶è¿è¡Œåº”用程åº?#8221; 一节中的两个步骤。还需要从 Sun çš?JSF 站点åQˆå‚è§?参考资æ–?/a>åQ‰ä¸‹è½½åƈ解压 jsf-1_1_01.zip。将 jsf-1.1.X.zip 中的所有文件复制到 JSFAcegiSample 应用½E‹åºçš?WEB-INF/lib æ–‡äšg夹中ã€?/p>

从浏览器讉K—® http://localhost:8080/JSFAcegiSampleåQŒå¯ä»¥è°ƒç”¨ç¤ºä¾‹åº”用程序。JSFAcegiSample 应用½E‹åºæ˜„¡¤ºä¸€ä¸ªçƒ¦å¼•页面和一个登录页面,索引™åµé¢ä¸­åŒ…含受保护资源的链接。所有受保护™åµé¢éƒ½æ˜¯ä½¿ç”¨ JSF ¾l„äšg开发的åQŒè€?Acegi 提供ç™Õd½•™åµé¢òq¶æ‰§è¡Œèín份验证和授权ã€?/p>



¾l“束è¯?/span>

在本文中åQŒäº†è§£äº†å¦‚何配置 Acegi 以保æŠ?JSF 应用½E‹åºã€‚还详细了解äº?JSF å’?Acegi ¾l„äšg如何在一ä¸?servlet 容器的框架中协作。最后,ž®è¯•˜qè¡Œäº†ä¸€ä¸ªç¤ºä¾?JSF-Acegi 应用½E‹åºã€?/p>

关于实现 JSF 应用½E‹åºçš?Acegi 安全性,˜q˜æ¶‰åŠåˆ°æ›´å¤šå†…容。本¾pÕdˆ—的下一½‹‡æ–‡ç« å°†æ¼”示如何使用 Acegi 保护å¯?JSF 的托½Ž?bean 的访问ã€?br />

来自: http://www.cnblogs.com/amboyna/archive/2008/03/25/1122089.html



]]>acegi,IBMçš„Acegi Security SystemåQ?åQ?http://www.aygfsteel.com/waterjava/archive/2008/05/08/199312.html狼爱上狸狼爱上狸Thu, 08 May 2008 10:47:00 GMThttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199312.htmlhttp://www.aygfsteel.com/waterjava/comments/199312.htmlhttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199312.html#Feedback0http://www.aygfsteel.com/waterjava/comments/commentRss/199312.htmlhttp://www.aygfsteel.com/waterjava/services/trackbacks/199312.html2007 òq?10 æœ?18 æ—?/p>
本文æ˜?Acegi Security Systerm 介绍的最后一部分åQˆå…±ä¸‰éƒ¨åˆ†ï¼‰åQŒBilal Siddiqui ž®†å‘您介¾lå¦‚何保护对 Java ¾cÕd®žä¾‹çš„讉K—®åQŒä»Žè€Œç»“束本¾pÕdˆ—文章。通过本文了解ä¸ÞZ½•需要对 Java™ ¾cȝš„讉K—®˜q›è¡Œä¿æŠ¤åQŒSpring 如何创徏和保护对 Java ¾cÕd®žä¾‹çš„讉K—®ä»¥åŠå¦‚何å¯?Acegi ˜q›è¡Œé…ç½®ä»¥å®žçŽ?Java 应用½E‹åºçš„类安全性ã€?/blockquote>

˜q™æœŸå…±åˆ†ä¸‰éƒ¨åˆ†çš„¾pÕdˆ—文章介绍了如何ä‹Éç”?Acegi 安全¾pȝ»Ÿä¿æŠ¤ Java 企业应用½E‹åºã€‚系列文章的 ½W?1 部分 ½Ž€å•介¾läº† Acegi òq¶è§£é‡Šå¦‚何ä‹É用其内置的安全过滤器实现一个简单的、基äº?URL 的安全系¾lŸã€?a cmimpressionsent="1">½W?2 部分 ä»‹ç»äº†å¦‚ä½•ç¼–å†™è®¿é—®æŽ§åˆ¶ç­–ç•¥åÆˆž®†å…¶ä¿å­˜åˆîC¸€ä¸?LDAP 目录服务器,以及如何配置 Acegi 来与目录服务器进行交互,从而实现访问控制策略。第 3 部分åQˆä¹Ÿæ˜¯æœ¬¾pÕdˆ—的最后一½‹‡æ–‡ç« ï¼‰ž®†æ¼”½Cºå¦‚何在企业应用½E‹åºä¸­ä‹Éç”?Acegi 保护å¯?Java ¾cÕd®žä¾‹çš„讉K—®ã€?

首先我将介绍何时需要对 Java ¾c»è®¿é—®è¿›è¡Œä¿æŠ¤ï¼ŒåŒ…括文中引用的两个典型企业应用程序场景。之后,我将解释 Spring 的反转控åˆÓž¼ˆIOCåQ‰æ¡†æž¶å¦‚何创建可ä»?JSP æˆ?servlet 讉K—®çš?Java ¾cÕd®žä¾‹ã€‚我˜q˜å°†ä»‹ç»æœ‰å…³ bean 代理 的重要概念,Spring 正是使用它过滤对 Java ¾cȝš„讉K—®ã€‚最后,我将介绍如何å¯?Acegi 的方法安全性拦截器˜q›è¡Œé…ç½®ä»¥æŽ§åˆ¶å¯¹ Java ¾cȝš„讉K—®ã€‚我ž®†å¯¹ ½W?2 部分 中的½CÞZ¾‹½E‹åº˜q›è¡Œå¢žå¼ºåQŒäؓ实现安全çš?Java 对象提供支持åQŒä»Žè€Œç»“束本¾pÕdˆ—的最后一½‹‡æ–‡ç« ã€?

ç”׃ºŽæœ¬æ–‡çš„讨论构建在本系列前两部分的内容之上åQŒå› æ­¤ä¼š¾lå¸¸å¼•用åˆ?½W?1 部分 å’?½W?2 部分 中的讨论和示例。因此,在ç‘ô¾l­é˜…è¯ÀLœ¬æ–‡ä¹‹å‰ï¼Œåœ¨å…¶ä»–浏览器½H—口中打开前两期文章将有助于理解本文内宏V€?/p>

保护 Java ¾cȝš„用例

您可能还记得åQŒæˆ‘曑֜¨æœ¬ç³»åˆ—的开头部分简单介¾läº† 企业应用½E‹åºå®‰å…¨æ€?/a>。在那次讨论中我曾提到过一¿Uåœºæ™¯ï¼Œå…¶ä¸­ URL å®‰å…¨æ€§åÆˆä¸èƒ½å®Œå…¨æ»¡èƒö˜q™ç§åœºæ™¯çš„安全需求:

假设有这样一ä¸?PDF 文档åQŒå…¶ä¸­åŒ…含了某制造业公司生äñ”的特定äñ”品的数据。文档的一部分包含了设计数据,ž®†ç”±å…¬å¸è®¾è®¡éƒ¨åˆ†˜q›è¡Œ¾~–辑和更新。文档另一部分包含生äñ”¾lç†ž®†ä‹É用到的生产数据。对于此¾cÕdœºæ™¯ï¼Œéœ€è¦å®žçŽ°æ›´åŠ ç»†¾_’度的安全性,å¯ÒŽ–‡æ¡£çš„不同部分应用不同的访问权限ã€?/blockquote>

在ç‘ô¾l­é˜…è¯ÖM¹‹å‰ï¼Œè¯¯‚€ƒè™‘更多的应用程序场景,除了实现 URL 安全性以外,˜q™äº›åœºæ™¯˜q˜è¦æ±‚您对单独的¾c»è®¿é—®è¿›è¡Œä¿æŠ¤ã€?/p>

业务自动�/span>

业务自动化应用程序中的工作流由多个流½E‹ç»„成。例如,病理学实验室中执行血液测试的工作‹¹ç”±è‹¥å¹²ä¸ªæ­¥éª¤ç»„成,其中每个步骤可看作一个业务流½E‹ï¼š

  1. å·¥ä½œäººå‘˜ä»Žç—…äººå¤„é‡‡é›†è¡€æ¶²æ ·æœ¬åÆˆä¸ºå…¶åˆ†é…ä¸€ä¸?IDã€?
  2. 实验室技术äh员对æ ähœ¬˜q›è¡Œå¿…è¦çš„æµ‹è¯•åÆˆå‡†å¤‡‹¹‹è¯•¾l“æžœã€?
  3. 由具备相应资格的病理学专家根据测试结果编写测试报告�

很明显,每个‹¹ç¨‹åˆ†åˆ«ç”±å•独的授权用户执行。未授权的用户则无权执行‹¹ç¨‹ã€‚例如,实验室研½I¶äh员只负责准备试验¾l“æžœåQŒè€Œæ— æƒç¼–写测试报告ã€?/p>

几乎所有的业务自动化应用程序都普遍使用授权的业务流½E‹ã€‚通常åQŒæ¯ä¸ªä¸šåŠ¡æµ½E‹è¢«å®žçްä¸ÞZ¸€ä¸?Java ¾c»ï¼Œòq¶ä¸”需要ä‹É用合适的讉K—®æŽ§åˆ¶½{–ç•¥å¯Òމ€æœ‰ç±»å®žæ–½ä¿æŠ¤ã€?/p>

企业对企业(Business-to-businessåQ‰é›†æˆ?/span>

Business-to-business (B2B) 集成指一¿Uå¸¸è§çš„场景åQŒå…¶ä¸­çš„两个企业实体需要彼此公开各自的特定功能。例如,å®ùN¦†å¯èƒ½å‘旅游公司公开其房间预订功能,而后者ä‹É用该功能为游客预订空闲的戉K—´ã€‚作为合作伙伴的旅游公司可能å…ähœ‰ä¸€ä¸ªç‰¹å®šçš„订房率。在˜q™ä¸ªåœºæ™¯ä¸­ï¼Œå®ùN¦†çš„订房系¾lŸå¿…™åÕd…ˆå¯ÒŽ—…游公司进行èín份验证,然后才能允许他们讉K—®æ‰€é€‰æ‹©çš„ç±»åQŒä»¥ä¾¿æŒ‰ç…§ç‰¹å®šçš„订房率进行房间预订ã€?/p>



回页�/strong>


使用 Spring 创徏 Java 对象

现在您已¾läº†è§£äº†å¯?Java ¾cȝ¤ºä¾‹çš„讉K—®˜q›è¡Œä¿æŠ¤çš„重要性。在介绍能够实现更高¾U§å®‰å…¨æ€§çš„ Acegi 新功能之前,我将引导您回™å?Spring 框架的几个关键特性,您需要了解这些内å®Òމèƒ½ç‘ô¾l­åŽæ–‡çš„½CÞZ¾‹ã€?/p>

首先对一äº?Java ¾c»è¿›è¡Œé…¾|®åƈ执行实例化ã€?a cmimpressionsent="1">½W?1 部分 曾介¾lè¿‡åQŒJava ¾cÕdœ¨ Spring çš?XML 配置文äšg中进行配¾|®ã€‚在 Spring 配置文äšg中配¾|?Java ¾cȝš„˜q‡ç¨‹ä¸?Acegi ˜q‡æ×o器的配置˜q‡ç¨‹å®Œå…¨ç›¸åŒåQŒå› æ­¤è¿™é‡Œä¸å¤šåšä»‹ç»ã€‚相反,我们ž®†æŸ¥çœ‹æ¸…å?1åQŒå®ƒå±•示了名ä¸?publicCatalog çš?bean 的配¾|®ï¼š


清单 1. Acegi XML 配置文äšg
            <beans>
            <bean id="publicCatalog"
            class="com.catalog.PublicCatalog" />
            <!--Other bean tags -->
            <beans>
            

了解 Spring çš?IOC 框架如何ä»?XML 配置文äšgè¯Õd– Java ¾cÖM¿¡æ¯ä»¥åŠå¦‚何进行实例化åQŒè¿™ä¸€ç‚šwžå¸”R‡è¦ã€‚您可能˜q˜è®°å¾—,我在¾pÕdˆ—文章çš?½W?1 部分 中ä‹É用一ä¸?web.xml æ–‡äšg配置 <listener> 标记åQŒå®ƒæŒ‡å‘åäØ“ ContextLoaderListener 的类ã€?code>ContextLoaderListener 装蝲 Spring çš?IOC 框架òq¶åˆ›å»?Java 对象。您可以参è€?½W?1 部分的清å?8 查看全部内容。图 1 也对此进行了描述åQ?/p>
å›?1. 装蝲 Spring çš?IOC 框架òq¶åˆ›å»?Java 对象
装蝲 Spring çš?IOC 框架òq¶åˆ›å»?Java 对象的步éª? src=

现在我们ž®†è¯¦¾l†è®¨è®ø™¿™äº›æ­¥éª¤ï¼š

  1. 当初始化 Acegi 应用½E‹åºæ—Óž¼Œservlet 容器åQˆæœ¬ä¾‹ä¸­ä¸?Apache TomcatåQ‰åˆ›å»ÞZº†ä¸€ä¸?servlet 上下æ–?/em>åQŒå…¶ä¸­ä¿å­˜äº†æœ‰å…³åº”用½E‹åºèµ„源的信息,例如 JSP ™åµé¢å’Œç±»ã€?br />
  2. servlet 容器通知 ContextLoaderListener ¾cÕdº”用程序正在启动ã€?br />
  3. ContextLoaderListener ¾cÕdˆ›å»ÞZ¸€ä¸?Web 应用½E‹åºä¸Šä¸‹æ–‡ä»¥ä¿å­˜åº”用½E‹åºä¸­ç‰¹å®šäºŽ Spring 的资源信息。借助 Spring çš?IOC 框架åQŒæ‚¨å¯ä»¥è£…蝲自己的自定义应用½E‹åºä¸Šä¸‹æ–‡ã€‚要创徏应用½E‹åºä¸Šä¸‹æ–‡ï¼Œž®†ä‹É用名ä¸?ContextLoader 的上下文装蝲器类装蝲应用½E‹åºä¸Šä¸‹æ–‡ã€?br />
  4. 如果应用½E‹åºä¸éœ€è¦å®šä¹‰è‡ªå·Þqš„应用½E‹åºä¸Šä¸‹æ–‡ï¼Œåˆ™å¯ä»¥ä‹É用名ä¸?XMLWebApplicationContext 的类åQŒå®ƒæ˜?Spring 框架的一部分òq¶æä¾›å¯å¤„理 Spring XML 配置文äšg的功能。Acegi 应用½E‹åºä½¿ç”¨çš„æ˜¯ Spring çš?XML 配置文äšgåQŒå› æ­¤æœ¬æ–‡ä»…讨论ç”?XMLWebApplicationContext ¾c»è¡¨½Cºçš„应用½E‹åºä¸Šä¸‹æ–‡ã€‚在本例中,上下文装载器å¯?XMLWebApplicationContext ¾c»è¿›è¡Œå®žä¾‹åŒ–åQŒåŽè€…表½Cºæ‚¨çš?Acegi 应用½E‹åºçš„应用程序上下文。上下文装蝲器还åœ?Web 应用½E‹åºä¸Šä¸‹æ–‡ä¸­è®„¡½® servlet 上下文(于步éª?1 中创建)的引用ã€?br />
  5. XMLWebApplicationContext ¾cÕd¯¹ XML 配置文äšg˜q›è¡Œè§£æžåQŒèŽ·å¾—å…³äº?Java ¾cȝš„信息òq¶å°†ä¿¡æ¯è£…蝲到其他内部对象中ã€?br />
  6. XMLWebApplicationContext ¾cÕd¯¹ XML 配置文äšg中指定的所æœ?Java ¾c»è¿›è¡Œå®žä¾‹åŒ–ã€?code>XMLWebApplicationContext ¾cÀL£€æŸ?XML 配置文äšg中经˜q‡é…¾|®çš„ Java bean 是否依赖其他çš?Java 对象。如果是的话åQ?code>XMLWebApplicationContext ¾cÕd°†é¦–先对其ä»?bean 所依赖çš?bean ˜q›è¡Œå®žä¾‹åŒ–。通过˜q™ç§æ–¹å¼åQ?code>XMLWebApplicationContext ¾cÕdˆ›å»ÞZº† XML 配置文äšg中定义的所æœ?bean 的实例。(注意åQŒæ­¥éª?6 假定 XML 配置文äšg中所æœ?bean 都不要进行保护,½EåŽä¸€èŠ‚å°†ä»‹ç»æ­¥éª¤ 5 和步éª?6 之间执行的额外步骤,从而保护对此处创徏çš?Java bean 的访问)ã€?br />
  7. XMLWebApplicationContext ¾cÕd°†æ‰€æœ?bean 保存在一个数¾l„中ã€?

您现在已了解到如何从 XML 配置文äšg中装è½?bean 定义òq¶åˆ›å»?Java ¾cȝš„实例。接下来åQŒæˆ‘ž®†å‘您介¾l?Spring bean 代理òq¶è§£é‡Šå®ƒå¯¹äºŽä¿æŠ¤ Java ¾cÕd®žä¾‹çš„重要性ã€?/p>



回页�/strong>


使用 bean 代理

上一节讨è®ÞZº† Spring çš?IOC 框架å¯?Java 对象˜q›è¡Œå®žä¾‹åŒ–。要保护å¯?Java 对象的访问,Spring çš?IOC 框架使用äº?bean 代理 的概å¿üc€‚本节首先介¾lå¦‚何配¾|?bean 代理åQŒç„¶åŽæ¼”½C?Spring çš?IOC 框架如何创徏代理对象ã€?/p>

�Java 对象配置代理

如果希望创徏 bean 代理åQŒSpring IOC 框架要求您对代理创徏å™?bean 的实例进行配¾|®ã€‚Spring çš?IOC 框架使用代理创徏器创å»ÞZ»£ç†å¯¹è±¡ã€‚清å?2 ä¸ÞZ»£ç†åˆ›å»ºå™¨ bean 的配¾|®æ–‡ä»Óž¼Œç”¨äºŽä¿æŠ¤åäØ“ privateCatalog çš?Java 对象åQ?/p>
清单 2. 代理 bean 配置
            <bean id="proxyCreator"
            class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            <property name="beanNames">
            <list>
            <value>privateCatalog</value>
            <!--Names of other beans to be proxied -->
            </list>
            </property>
            <property name="interceptorNames">
            <list>
            <value>privateCatalogSecurityInterceptor</value>
            </list>
            </property>
            </bean>
            

如清å?2 所½Cºï¼Œ<bean> 标记å…ähœ‰ä¸€ä¸?class 属性,其å€égØ“ org.springframework.aop.framework.autoproxy. BeanNameAutoProxyCreatorã€?code>BeanNameAutoProxyCreator ¾cÀL˜¯ Spring IOC 框架的一部分åQŒå¯ä»¥è‡ªåŠ¨åˆ›å»?bean 代理。Spring 框架提供äº?BeanPostProcessor 接口åQŒå®ƒæä¾›äº†ä¸€¿Uå¯æ‰©å±•机制åQŒå…è®¸åº”用程序编写自å·Þqš„逻辑来创å»?bean 代理。Spring çš?BeanNameAutoProxyCreator ¾cÕd®žçŽîCº† BeanPostProcessor 接口òq¶æä¾›æ‰€æœ‰å¿…需的代理创建逻辑来保æŠ?Java ¾c…R€‚因此,本文中您无需实现 BeanPostProcessor 接口ã€?/p>

在创å»?bean 代理æ—Óž¼ŒBeanNameAutoProxyCreator ¾cÖMؓ所有由 beanNames 属性定义的 bean 创徏代理åQˆå‚è§?清单 2 ä¸?<bean> 标记的第一ä¸?<property> 子元素)ã€?code>beanNames 属性在 <list> 标记中包含一ä¸?bean 名称列表。在 清单 2 ä¸­ï¼Œæˆ‘åªå¯¹å¸Œæœ›äØ“ä¹‹åˆ›å»ÞZ»£ç†çš„ privateCatalog bean˜q›è¡Œäº†é…¾|®ã€?/p>

现在查看 清单 2 ä¸?<bean> 标记的第二个 <property> 子元素。它指定了名ä¸?interceptorNames 的代理,它将一个或多个拦截器的名称ž®è£…èµäh¥ã€‚我ž®†åœ¨åŽæ–‡è¯¦ç»†è®¨è®ºæ‹¦æˆªå™¨æ¦‚å¿üc€‚çŽ°åœ¨ï¼Œåªéœ€äº†è§£æ‹¦æˆªå™¨å¯ä»¥æ‹¦æˆªç”¨æˆ·åÆˆåœ¨ç”¨æˆ¯‚®¿é—?bean 之前实现讉K—®æŽ§åˆ¶½{–ç•¥ã€?/p>

现在åQŒæ‚¨å·²äº†è§£äº†å¦‚何对希望进行保护的 bean 配置代理。接下来åQŒæ‚¨ž®†äº†è§?Spring çš?IOC æ¡†æž¶å¦‚ä½•åœ¨å†…éƒ¨äØ“åº”ç”¨½E‹åºçš?bean 创徏代理对象ã€?/p>

Spring IOC 发挥效用

åœ?“使用 Spring 创徏 Java 对象” 的步éª?5 和步éª?6 中,您了解了 XMLWebApplicationContext ¾cÕd¦‚何从 XML 配置文äšg中读å?bean 定义òq‰™šåŽåˆ›å»?bean 实例。在创徏 bean 实例之前åQ?code>XMLWebApplicationContext ¾cÕd°†‹‚€æŸ?XML 配置文äšg是否包含ä»ÖM½•代理创徏å™?beanåQˆå³å®žçް BeanPostProcessor 接口çš?beanåQ‰é…¾|®ã€‚如果存在该 beanåQŒå®ƒž®†è¦æ±‚代理创建器为您希望˜q›è¡Œä¿æŠ¤çš?bean 创徏 bean 代理ã€?/p>

现在考虑代理创徏器如何在内部创徏代理对象åQ?/p>

  1. 代理创徏器(å?BeanNameAutoProxyCreator ¾c»ï¼‰è£…蝲 清单 2 中配¾|®çš„ beanNames 属性文件中指定的所æœ?bean 名称ã€?br />
  2. 代理创徏器ä‹Éç”?bean 名称装蝲各自çš?Java ¾c»ï¼Œ˜q™äº›¾cÖM‹É用了每个 bean 定义çš?class 属性ã€?br />
  3. 代理创徏器创å»?清单 2 所½Cºçš„ interceptorNames 属性中指定的拦截器的实例ã€?br />
  4. 最后,代理创徏器创å»ÞZ¸€ä¸?Cglib2AopProxy ¾cȝš„实例åQŒå°†æ‰€æœ?bean 名称åQˆæ­¥éª?2åQ‰å’Œæ‹¦æˆªå™¨ï¼ˆæ­¥éª¤ 3åQ‰ä¼ é€’到 Cglib2AopProxy ¾c…R€?code>Cglib2AopProxy ¾cÀL˜¯ Spring 框架的一部分òq¶ç”¨äºŽç”ŸæˆåŠ¨æ€ä»£ç†å¯¹è±¡ã€‚åœ¨æœ¬ä¾‹ä¸­ï¼ŒCglib2AopProxy ¾cÕd°†åˆ›å¾å®‰å…¨ bean 讉K—®æŽ§åˆ¶æ‰€éœ€çš„代理对象ã€?

Cglib2AopProxy ¾cÕd®žçŽîCº†ä¸¤ä¸ªåäØ“ AOPProxy å’?MethodInterceptor 的接口ã€?code>AOPProxy 接口ç”?Spring 框架提供åQŒè¡¨½Cºæ‚¨å¸Œæœ›˜q›è¡Œä»£ç†çš„实é™?beanåQŒå› æ­¤å®ƒä¸Žæ‚¨çš?bean 公开相同的方法ã€?code>MethodInterceptor 接口也源äº?AOP 框架åQŒå®ƒåŒ…含的方法可以在用户试图讉K—®æ‚¨å·²æ‰§è¡Œä»£ç†çš?bean 时接受控制权。这意味着 MethodInterceptor 接口处理来自用户的请求以讉K—®æ‰§è¡Œ˜q‡ä»£ç†çš„ bean。由äº?Cglib2AopProxy ¾cÕdŒæ—¶å®žçŽîCº† AOPProxy å’?MethodInterceptor 接口åQŒå› æ­¤å®ƒæä¾›äº†å®Œæ•´çš„功能åQŒæ—¢å¯ä»¥æä¾›¾lè¿‡ä»£ç†çš?beanåQŒä¹Ÿå¯ä»¥å¤„理用户è¯äh±‚以访问代ç?beanåQˆå‚è§?参考资料小èŠ?/a> 中有å…?AOP 的讨论文章的链接åQ‰ã€?/p>

执行完前面的步骤后,您现在具有了所需的代理对象。因æ­?XMLWebApplicationContext ¾cÕd°†å®‰å…¨ bean 的代理(而不是实际的 beanåQ‰ä¿å­˜åœ¨ “使用 Spring 创徏 Java 对象” 的步éª?7 中的同一个数¾l„中ã€?





回页�/strong>


讉K—®æ‰§è¡Œ˜q‡ä»£ç†çš„ Java 对象

在前面的几节中,您了解了 Spring 如何创徏公有 bean 和私æœ?bean。出于本文的目的åQŒæ‚¨å¯å°†å…¬æœ‰ bean è§†äØ“ä½¿ç”¨ä»£ç†ä¿æŠ¤çš„ä¸å®‰å…¨çš„ç§æœ?bean。现在我们来看一下客æˆähœºåº”用½E‹åºä¸ø™®¿é—®å…¬æœ?bean 和私æœ?bean 而必™å»éµå¾ªçš„一¾pÕdˆ—步骤ã€?/p>

清单 3 展示äº?publicCatalog å’?privateCatalog 两个 bean çš?XML 配置ã€?code>publicCatalog bean 意味着公共讉K—®åQŒå› æ­¤ä¸éœ€è¦ä‹Éç”?bean 代理ã€?code>privateCatalog bean 意味着只能由指定用戯‚®¿é—®ï¼Œå› æ­¤å¿…须加以保护。我在清å?3 中包含了 privateCatalog bean çš?bean 代理配置åQ?/p>
清单 3. publicCatalog �privateCatalog bean �XML 配置
            <beans>
            <bean id="publicCatalog" class="sample.PublicCatalog"/>
            <bean id="privateCatalog" class="sample.PrivateCatalog"/>
            <!-- proxy configuration for privateCatalog bean -->
            <bean id="proxyCreator"
            class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            <property name="beanNames">
            <list>
            <value>privateCatalog</value>
            <!--Names of other beans to be proxied -->
            </list>
            </property>
            <property name="interceptorNames">
            <list>
            <value>privateCatalogSecurityInterceptor</value>
            </list>
            </property>
            </bean>
            <beans>
            

应用½E‹åºå¯ä»¥ä½¿ç”¨æ¸…单 4 中的代码讉K—®æ¸…单 3 中配¾|®çš„ publicCatalog å’?privateCatalog Java bean。注意,清单 4 中显½Cºçš„ Java 代码可位äº?JSP ™åµé¢æˆ–位于服务器ç«?Java 应用½E‹åºçš?bean 中ã€?/p>
清单 4. 讉K—®å®‰å…¨å’Œä¸å®‰å…¨ Java bean 的客æˆähœºåº”用½E‹åºä»£ç 
            //Step 1: Fetching an instance of the application context
            XMLWebApplicationContext applicationCtx =
            WebApplicationContextUtils.getWebApplicationContext(
            this.getServletConfig().getServletContext());
            //Step 2: Fetching an insecure bean from the application context
            PublicCatalog publicCatalog =
            (PublicCatalog) applicationCtx.getBean("publicCatalog");
            //Step 3: Calling a method of the insecure bean
            String publicData = publicCatalog.getData();
            //Step 4: Fetching a secure bean from the application context
            PrivateCatalog privateCatalog =
            (PrivateCatalog) applicationCtx.getBean("privateCatalog");
            //Step 5: Calling a method of the secure bean
            String privateData = privateCatalog.getData();
            

下面ž®†è¿›ä¸€æ­¥è®¨è®ºæ¸…å?4 中的步骤åQ?/p>

  • 步骤 1åQšå–回一个应用程序上下文实例
    当应用程序希望访é—?XML 配置文äšg中配¾|®çš„ Java bean æ—Óž¼Œå®ƒå¿…™åÕd–回您åœ?“使用 Spring 创徏 Java 对象” 的步éª?4 中见到的 XMLWebApplicationContext 对象ã€?code>XMLWebApplicationContext 对象包含å¯?XML 配置文äšg配置的所æœ?Java beans 的引用ã€?br />
  • 步骤 2åQšä»Žåº”用½E‹åºä¸Šä¸‹æ–‡ä¸­å–回不安全的 bean
    您现在具有一个对 XMLWebApplicationContext 对象的引用ã€?code>XMLWebApplicationContext ¾cÕd…¬å¼€äº†ä¸€ä¸?getBean() æ–ÒŽ³•åQŒå®ƒåŒ…含 bean 的名¿U°åƈ在数¾l„中查找 “使用 Spring 创徏 Java 对象” 步骤 7 中准备的 bean。在本例中,è¯?bean ä¸?publicCatalogåQˆæœªæ‰§è¡Œ˜q‡ä»£ç†ï¼‰åQŒå› æ­?XMLWebApplicationContext ž®†è¿”回实际的 beanã€?br />
  • 步骤 3åQšè°ƒç”¨ä¸å®‰å…¨ bean 的方æ³?/strong>
    现在您可以调用步éª?2 中获得的 publicCatalog bean çš„ä“Q何方法。例如,清单 4 昄¡¤ºçš?getData() æ–ÒŽ³•调用的执行没有应用ä“Qä½•è®¿é—®æŽ§åˆ¶åÆˆå‘åº”ç”¨ç¨‹åºè¿”å›žç±»åˆ«æ•°æ®ã€?br />
  • 步骤 4åQšä»Žåº”用½E‹åºä¸Šä¸‹æ–‡å–回安å…?bean
    安全 bean 与不安全 bean 的取回方式类ä¼û|¼ŒæƒŸä¸€åŒºåˆ«æ˜¯ï¼šå½“您通过调用 getBean() æ–ÒŽ³•ž®è¯•取回安全 bean æ—Óž¼Œæ‚¨å°†èŽ·å¾—å®‰å…¨å¯¹è±¡çš„ä»£ç†è€Œä¸æ˜¯å®žé™…çš„å¯¹è±¡ã€‚è¯¥ä»£ç†ž®±æ˜¯æˆ‘在 “Spring IOC 发挥效用” 步骤 4 中解释的ç”?Spring 框架创徏的同一个对象ã€?br />
  • 步骤 5åQšè°ƒç”¨å®‰å…?bean 的方æ³?/strong>
    当调用安å…?bean 的方法时åQŒæ‚¨åœ?步骤 4 中获得的代理对象ž®†ä¸€ä¸ªæ–¹æ³•调用请求分配给拦截器。拦截器ž®†æ£€æŸ¥è¯•图访问方法的用户是否å…ähœ‰ç›¸åº”的访问权åQŒä»Žè€Œå¤„理方法调用请求ã€?

您现在应该对 Spring 框架如何创徏 Java 对象以及客户机应用程序如何与之交互有了清晰的了解。了解了˜q™äº›å†…容后,ž®±æ›´åŠ å®¹æ˜“ç†è§£åÆˆåˆ©ç”¨ Acegi 的方法安全性拦截器åQŒä¸‹ä¸€èŠ‚å°†å…·ä½“ä»‹ç»è¯¥ä¸»é¢˜ã€?/p>



回页�/strong>


配置 Acegi 的方法安全性拦截器

只要应用½E‹åºè¯•图讉K—®ç”?Acegi 安全¾pȝ»Ÿä¿æŠ¤çš?bean æ–ÒŽ³•åQŒè¯·æ±‚将被自动传递到 Acegi 的方法安全性拦截器。方法安全性拦截器的作用就是控制对安全 Java bean 的方法的讉K—®ã€‚拦截器使用 Acegi çš„èín份验证和授权框架¼‹®è®¤ç”¨æˆ·æ˜¯å¦å…ähœ‰æƒåˆ©è°ƒç”¨å®‰å…¨ Java bean 的方法,然后相应åœîC½œå‡ºå“åº”ã€?/p>

清单 5 展示 Acegi 的方法安全性拦截器的示例配¾|®ï¼š


清单 5. Acegi 的方法安全性拦截器的示例配¾|?/strong>
            <bean id="privateCatalogSecurityInterceptor"
            class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
            <property name="authenticationManager">
            <ref bean="authenticationManager"/>
            </property>
            <property name="accessDecisionManager">
            <ref bean="accessDecisionManager"/>
            </property>
            <property name="objectDefinitionSource">
            <value>
            sample.PrivateCatalog.getData=ROLE_HEAD_OF_ENGINEERING
            <!-- Roles required by other beans -->
            </value>
            </property>
            </bean>
            

清单 5 所½Cºçš„æ‹¦æˆªå™¨é…¾|®åŒ…含三个需要进行配¾|®çš„属性,可以保护å¯?Java bean 的访问:authenticationManagerã€?code>accessDecisionManager å’?objectDefinitionSourceã€?/p>

回忆一下,您在本系列第 1 部分çš?配置íw«ä†¾éªŒè¯å¤„理˜q‡æ×oå™?/a> 中曾å¯?authenticationManager 属性进行了配置ã€?code>authenticationManager 属性的作用是对用户˜q›è¡Œíw«ä†¾éªŒè¯ã€?/p>

您在本系列的½W¬äºŒ½‹‡æ–‡ç« ä¸­äº†è§£äº?accessDecisionManager 属性。这个访问决½{–管理器负责制定授权决策。在允许对一个安å…?bean ˜q›è¡Œè®‰K—®ä¹‹å‰åQŒæ–¹æ³•安全拦截器使用 authenticationManager å’?accessDecisionManager 属性对用户˜q›è¡Œíw«ä†¾éªŒè¯å’ŒæŽˆæƒã€?/p>

现在查看 清单 5 中配¾|®çš„ objectDefinitionSource 属性。它¾cÖM¼¼äºŽç¬¬ 1 部分中出现的 objectDefinitionSource 属性。以前的 objectDefinitionSource 包含¾cÖM¼¼äº?/protected/* å’?/** ˜q™æ ·çš?URLåQŒæ¸…å?5 中的 objectDefinitionSource 属性指定类和方法名åQ›ä¾‹å¦‚,sample.PrivateCatalog 是之前执行过代理的类的名¿UŽÍ¼Œè€?getData 是您希望对其控制用户讉K—®çš„æ–¹æ³•的名字ã€?/p>

当用戯‚®¿é—?PrivateCatalog bean çš?getData() æ–ÒŽ³•æ—Óž¼ŒæŽ§åˆ¶æƒå°†è‡ªåŠ¨ä¼ é€’ç»™æ‹¦æˆªå™¨ã€‚æ‹¦æˆªå™¨ä½¿ç”¨ Acegi 框架‹‚€æŸ¥ç”¨æˆïLš„业务角色是否ä¸?ROLE_HEAD_OF_ENGINEERINGåQˆç‰¹å®šäºŽæœ¬æ–‡çš„示例)。如果是的话åQŒæ‹¦æˆªå™¨ž®†å…è®¸å¯¹ getData() æ–ÒŽ³•˜q›è¡Œè®‰K—®ã€‚如果拦截器发现用户角色不是 ROLE_HEAD_OF_ENGINEERINGåQŒåˆ™æ‹’绝讉K—®ã€?/p>

下一节将查看一个示ä¾?Acegi 应用½E‹åºåQŒå®ƒž®†å®žçŽ°æ‚¨ç›®å‰æ‰€äº†è§£çš„æ‰€æœ‰æ¦‚å¿üc€?/p>



回页�/strong>


½CÞZ¾‹ Acegi 应用½E‹åº

本文çš?下蝲源代ç ?/a> 包含了一个名ä¸?AcegiMethodSecurity 的示例应用程序,可按照以下方法进行配¾|®å’Œéƒ¨çÖvåQ?/p>

  1. 使用用户信息填充 LDAP 服务器ã€?a cmimpressionsent="1">下蝲的示例应用程åº?/a> 包含一ä¸?LDIF æ–‡äšgåQŒå…¶ä¸­å«æœ‰é¢„备装载到 LDAP 服务器的用户信息。关于如何将 LDIF æ–‡äšg导入åˆ?LDAP 服务器,请参考第 2 部分çš?“填充服务å™?/a>” 一节。注意,该应用程序涉及与½W?2 éƒ¨åˆ†ç›¸åŒçš„ç”¨æˆøP¼ˆaliceã€?code>bob å’?specialUseråQ‰ã€?br />
  2. ž®†æœ¬æ–‡ä¸‹è½½æºä»£ç ä¸­çš„ acegiMethodSecurity.war æ–‡äšg复制åˆ?Tomcat 安装目录中的 webapps 目录ã€?br />
  3. ž®?Acegi çš?jar æ–‡äšg复制到示例应用程序的 WEB-INF/lib æ–‡äšg夏V€‚(有关内容请参考第 1 部分çš?“部çÖv和运行应用程åº?/a>” 一节ã€?åQ?br />
  4. 下蝲 cglib-full-2.0.2.jar æ–‡äšgòq¶å°†å…¶å¤åˆ¶åˆ°½CÞZ¾‹åº”用½E‹åºçš?WEB-INF/lib æ–‡äšg夏V€?

启动 Tomcat òq¶å°è¯•运行示例应用程序ã€?/p>

˜qè¡Œ½CÞZ¾‹åº”用½E‹åº

通过从浏览器讉K—® http://localhost:8080/acegiMethodSecurity URL 可调用示例应用程序。AcegiMethodSecurity 昄¡¤ºçš„烦引页面包含两个链接(Catalog å’?LoginåQ‰ï¼Œå¦‚图 2 所½Cºï¼š


å›?2. ½CÞZ¾‹åº”用½E‹åºçš„主™åµé¢
½CÞZ¾‹åº”用½E‹åºçš„主™åµé¢

当单å‡Õdº”用程序的 Catalog 链接æ—Óž¼Œå®ƒå°†è¦æ±‚您进行登录。如果以 alice æˆ?specialUser çš„èín份进行登录,½CÞZ¾‹åº”用½E‹åºž®†æä¾?em>完整çš?/em> ¾cÕdˆ«åQŒåŒ…括公有数据和¿Uæœ‰æ•°æ®ã€‚这是因为在 清单 5 中,您对æ–ÒŽ³•安全性拦截器˜q›è¡Œäº†é…¾|®ï¼Œå…è®¸ç”¨æˆ·ä½¿ç”¨ ROLE_HEAD_OF_ENGINEERING 讉K—®¿Uæœ‰¾cÕdˆ«åQŒè€?alice å’?specialUser 都具有该讉K—®æƒã€‚另一斚w¢åQŒå¦‚果您ä»?bob çš„èín份登录,½CÞZ¾‹åº”用½E‹åºž®†ä»…昄¡¤ºå…¬æœ‰æ•°æ®ã€?/p>



回页�/strong>


为通过íw«ä†¾éªŒè¯çš„用户分配额外角è‰?/span>

本节ž®†æ¼”½Cºç»˜q‡å¢žå¼ºçš„½CÞZ¾‹åº”用½E‹åºã€‚增强后的示例应用程序将展示 Acegi 如何使您能够在运行时向通过íw«ä†¾éªŒè¯çš„用户äÍ时分配额外角艌Ӏ?

当安å…?beanåQˆä¾‹å¦?清单 3 çš?privateCatalog beanåQ‰è¦è®‰K—®ä¸€ä¸ªåŽŸåˆ›èµ„æºæ—¶åQŒæ‚¨å¯èƒ½éœ€è¦ä‹É用额外的角色。例如,您可能考虑到您的安å…?bean 需要通过 Java çš?Remote Method Invocation (RMI) 框架或一ä¸?Web 服务讉K—®æŸä¸ª˜qœç¨‹åº”用½E‹åºã€‚访问安å…?bean 的用户不会占用远½E‹åº”用程序要求访问用æˆäh‰€å…·å¤‡çš„业务角艌Ӏ?/p>

在本例中åQŒAcegi 首先‹‚€æŸ¥ç”¨æˆäh˜¯å¦ç»˜q‡æŽˆæƒæ¥è®‰K—®å®‰å…¨ bean。之后,Acegi 允许用户讉K—®å®‰å…¨ bean。当安全 bean 试图讉K—®˜qœç¨‹æœåŠ¡æ—Óž¼Œå®ƒéœ€è¦ä‹É用额外的业务角色。如果访问安å…?bean 的用户不具备额外角色åQŒå®‰å…?bean ž®×ƒ¸èƒ½æˆåŠŸè®¿é—®è¿œ½E‹æœåŠ¡ã€?/p>

run-as-replacement 机制

Acegi 框架提供了一¿Uåä¸?run-as-replacement 的简单机åˆÓž¼Œå…è®¸æ‚¨ä»…åœ¨æ–¹æ³•è°ƒç”¨æœŸé—´äØ“é€šè¿‡íw«ä†¾éªŒè¯çš„用户配¾|®ä¸€ä¸ªæˆ–多个额外角色。您可以使用 run-as-replacement æœºåˆ¶ä¸ø™®¿é—®è¿œ½E‹åº”用程序的安全 bean 配置额外角色。这意味着只要安全 bean 需要访问远½E‹åº”用程序,Acegi ž®†äؓ用户装蝲额外角色åQŒä»Žè€Œå…è®¸å®‰å…?bean 讉K—®˜qœç¨‹åº”用½E‹åºã€?/p>

清单 6 å¯?清单 5 中的æ–ÒŽ³•安全性拦截器的配¾|®è¿›è¡Œäº†å¢žå¼ºã€‚增强后的配¾|®ä‹É用了 run-as-replacement 机制ã€?/p>
清单 6. Acegi æ–ÒŽ³•安全性拦截器的增强配¾|?/strong>
            <bean id="privateCatalogSecurityInterceptor"
            class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
            <property name="authenticationManager">
            <ref bean="authenticationManager"/>
            </property>
            <property name="accessDecisionManager">
            <ref bean="accessDecisionManager"/>
            </property>
            <property name="runAsManager">
            
<bean id="runAsManager" class="org.acegisecurity.runas.RunAsManagerImpl">
<property name="key"> <value>myKeyPass</value> </property> </bean> </property> <property name="objectDefinitionSource"> <value> sample.PrivateCatalog.getData=ROLE_HEAD_OF_ENGINEERING,RUN_AS_MANAGER </value> </property> </bean>

清单 6 使用¾_—体昄¡¤ºäº†ä¸¤å¤„增强(ä¸?清单 5 相比åQ‰ã€‚第一处增å¼ÞZØ“ runAsManager 属性ã€?code>runAsManager 属性的作用是向通过íw«ä†¾éªŒè¯çš„用户动态添加角艌Ӏ‚出于这个目的,runAsManager 属性包含了 RunAsManagerImpl bean 的定义ã€?code>RunAsManagerImpl bean 只有在满­‘³ä¸‹é¢çš„æ¡äšg时才可变为活跃状态:åœ?objectDefinitionSource æ–ÒŽ³•的角色定义中扑ֈ°ä»?RUN_AS_ 为前¾~€çš„角艌Ӏ‚例如,PrivateCatalog.getData() æ–ÒŽ³•的角色定义(清单 6 中以¾_—体昄¡¤ºçš„第二处增强åQ‰å…·æœ‰ä¸€ä¸?RUN_AS_MANAGER 角色ã€?/p>

RunAsManagerImpl bean 包含一个名ä¸?key 的属性,它封装的加密键用于确保只ž®†é¢å¤–çš„è§’è‰²ä½œäØ“ run-as-replacement ½E‹åºçš„一部分生成ã€?/p>

当用戯‚°ƒç”?getData() æ–ÒŽ³•æ—Óž¼ŒRunAsManagerImpl bean å˜äØ“‹z»è·ƒçŠ¶æ€åÆˆåˆ›å¾åäØ“ RUN_AS_MANAGER 的额外角è‰ÔŒ¼Œä»Žè€Œå¯ç”?getData() æ–ÒŽ³•讉K—®˜qœç¨‹åº”用½E‹åºã€?/p>

增强的方法安全�/span>

本文çš?下蝲源代ç ?/a> 包含一个名ä¸?EnhancedAcegiMethodSecurity 的示例应用程序,它可以演½C?run-as-replacement 机制和程序。该应用½E‹åºž®†æ˜¾½CÞZ¸€ä¸ªå…·æœ?Catalog 链接的烦引页面。如果单å‡?Catalog 链接åQŒå°†è¦æ±‚˜q›è¡Œç™Õd½•ã€?/p>

ç™Õd½•后,EnhancedAcegiMethodSecurity 应用½E‹åºž®†äؓ您提供登录用户及其角色的完整信息。例如,如果ä»?alice æˆ?specialUser íw«ä†¾ç™Õd½•åQŒå°†å‘您昄¡¤ºç”¨æˆ·çš„æ‰€æœ‰ä¸šåŠ¡è§’è‰ÔŒ¼ŒåŒ…括额外创徏的äÍæ—¶çš„ RUN_AS_MANAGER 角色ã€?/p>

¾l“束è¯?/span>

在这份共分三部分的系列文章中åQŒæˆ‘介绍了如何ä‹Éç”?Acegi 安全¾pȝ»Ÿå¢žå¼ºåŸÞZºŽ URL 的安全性和åŸÞZºŽæ–ÒŽ³•çš„å®‰å…¨æ€§ã€‚æ‚¨äº†è§£äº†å¦‚ä½•è®¾è®¡è®¿é—®æŽ§åˆ¶ç­–ç•¥åÆˆž®†å®ƒä»¬æ‰˜½Ž¡åœ¨ç›®å½•服务器中åQŒå¦‚何对 Acegi ˜q›è¡Œé…ç½®ä»¥ä¸Žç›®å½•服务器进行通信åQŒä»¥åŠå¦‚何根据托½Ž¡åœ¨æœåŠ¡å™¨çš„è®‰K—®æŽ§åˆ¶½{–略制定íw«ä†¾éªŒè¯å’ŒæŽˆæƒå†³½{–ã€?/p>

本系列的最后一½‹‡æ–‡ç« ä¸»è¦ä»‹¾lä‹É用基于方法的安全性保æŠ?Java ¾cÕd®žä¾‹ã€‚文章还解释äº?Acegi å’?Spring 如何在内部创建和代理 Java 对象以及 bean 代理如何实现讉K—®æŽ§åˆ¶ã€‚文章包含了两个½CÞZ¾‹åº”用½E‹åºåQŒæ‚¨å¯ä»¥ä½¿ç”¨å®ƒä»¬˜q›ä¸€æ­¥ç ”½I¶æœ¬¾pÕdˆ—中学到的概念åQŒæ›´å¤šæœ‰å…³ä‹Éç”?Acegi 保护 Java 应用½E‹åºçš„内容,请参è§?参考资æ–?/a> ž®èŠ‚ã€?/p>

来自:http://www-128.ibm.com/developerworks/cn/java/j-acegi3/?

]]>acegi,IBMçš„Acegi Security SystemåQ?åQ?http://www.aygfsteel.com/waterjava/archive/2008/05/08/199311.html狼爱上狸狼爱上狸Thu, 08 May 2008 10:43:00 GMThttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199311.htmlhttp://www.aygfsteel.com/waterjava/comments/199311.htmlhttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199311.html#Feedback0http://www.aygfsteel.com/waterjava/comments/commentRss/199311.htmlhttp://www.aygfsteel.com/waterjava/services/trackbacks/199311.html2007 òq?6 æœ?21 æ—?/p>
了解äº?Acegi 安全¾pȝ»ŸåQˆAcegi Security SystemåQ‰çš„ 基础知识 后,我们ž®†ä»‹¾lè¯¥¾pȝ»Ÿçš„æ›´åŠ é«˜¾U§çš„应用。在本文中,Bilal Siddiqui 向您展示了如何结合ä‹Éç”?Acegi 和一ä¸?LDAP 目录服务器,实现灉|´»çš„具有高性能çš?Java™ 应用½E‹åºçš„安全性。还ž®†äº†è§£å¦‚ä½•ç¼–å†™è®¿é—®æŽ§åˆ¶ç­–ç•¥åÆˆž®†å…¶å­˜å‚¨åœ?ApacheDS 中,然后配置 Acegi 使其与目录服务器交互åQŒä»Žè€Œå®žçްèín份验证和授权的目的ã€?/blockquote>

˜q™æœŸå…±åˆ†ä¸‰éƒ¨åˆ†çš„¾pÕdˆ—文章介绍了如何ä‹Éç”?Acegi 安全¾pȝ»Ÿä¿æŠ¤ Java 企业应用½E‹åºã€‚在 本系列第一½‹‡æ–‡ç«?/a> 中,我介¾läº† Acegi òq¶è§£é‡Šäº†å¦‚何使用安全˜q‡æ×o器实çŽîC¸€ä¸ªç®€å•çš„åŸÞZºŽ URL 的安全系¾lŸã€‚在½W¬äºŒ½‹‡æ–‡ç« ä¸­åQŒæˆ‘ž®†è®¨è®?Acegi 的更加高¾U§çš„应用åQŒé¦–先我ž®†ç¼–å†™ä¸€ä¸ªè®¿é—®æŽ§åˆ¶ç­–ç•¥åÆˆž®†å…¶å­˜å‚¨åœ?ApacheDS 中,ApacheDS 是一个开源的 LDAP 目录服务器。我˜q˜å°†å±•示配置 Acegi 的方法,使它能够与目录服务器交互òq¶å®žçŽ°æ‚¨çš„è®¿é—®æŽ§åˆ¶ç­–ç•¥ã€‚æœ¬æ–‡çš„¾l“尾提供了一个示例应用程序,它ä‹Éç”?ApacheDS å’?Acegi 实现了一个安全的讉K—®æŽ§åˆ¶½{–ç•¥ã€?/p>

实现讉K—®æŽ§åˆ¶½{–略通常包含两个步骤åQ?/p>

  1. ž®†æœ‰å…³ç”¨æˆ·å’Œç”¨æˆ·è§’色的数据存储在目录服务器中ã€?
  2. ¾~–写安全代码åQŒå®ƒž®†å®šä¹‰æœ‰æƒè®¿é—®åƈ使用数据的äh员ã€?

Acegi ž®†å‡è½ÖM»£ç ç¼–写的工作åQŒå› æ­¤åœ¨˜q™ç¯‡æ–‡ç« ä¸­ï¼Œæˆ‘将展示如何ž®†ç”¨æˆ·å’Œç”¨æˆ·è§’色信息存储åˆ?ApacheDS 中,然后实现˜q™äº›ä¿¡æ¯çš„访问控制策略。在该系列的最后一½‹‡æ–‡ç« ä¸­åQŒæˆ‘ž®†å±•½Cºå¦‚何配¾|?AcegiåQŒå®žçް坹 Java ¾cȝš„安全讉K—®ã€?

您可以在本文的ä“Q何位¾|?下蝲样例应用½E‹åºã€‚参è§?参考资æ–?/a> 下蝲 Acegi、Tomcat å’?ApacheDSåQŒæ‚¨éœ€è¦ä‹É用它们运行样例代码和½CÞZ¾‹åº”用½E‹åºã€?/p>

LDAP 基础知识

轻量¾U§ç›®å½•访问协议(Lightweight Directory Access ProtocolåQŒLDAPåQ‰å¯èƒ½æ˜¯æœ€‹¹è¡Œçš„一¿Uå®šä¹‰æ•°æ®æ ¼å¼çš„协议åQŒå®ƒé’ˆå¯¹å¸¸è§çš„目录操作,例如对存储在目录服务器中的信息执行的è¯Õd–、编辑、搜索和删除操作。本节将½Ž€è¦è§£é‡Šäؓ什么目录服务器是属性文件存储安全信息的首选,òq¶å±•½Cºå¦‚何在 LDAP 目录中组¾l‡å’Œæ‰˜ç®¡ç”¨æˆ·ä¿¡æ¯ã€?

ä¸ÞZ»€ä¹ˆè¦ä½¿ç”¨ç›®å½•服务器?

本系列第一部分向您介绍了一¿Uç®€å•çš„æ–ÒŽ³•åQŒå¯ä»¥å°†ç”¨æˆ·ä¿¡æ¯ä»¥å±žæ€§æ–‡ä»¶çš„形式保存èµäh¥åQˆå‚è§?½W?1 部分åQŒæ¸…å?6åQ‰ã€‚属性文件以文本格式保存用户名、密码和用户角色。对于大多数真实应用½E‹åºè€Œè¨€åQŒä‹É用属性文件存储安全信息远˜qœä¸å¤Ÿã€‚各¿Uå„æ ïLš„理由表明åQŒç›®å½•服务器通常都是更好的选择。其中一个原因是åQŒçœŸå®žçš„企业应用½E‹åºå¯ä»¥è¢«å¤§é‡ç”¨æˆ¯‚®¿é—?—â€?通常是几千名用户åQŒå¦‚果应用程序将光™ƒ¨åˆ†åŠŸèƒ½å…¬å¼€¾l™ç”¨æˆ·å’Œä¾›åº”商时更是如此。频¾Jæœç´¢æ–‡æœ¬æ–‡ä»¶ä¸­éšæ„å­˜å‚¨çš„信息,˜q™æ ·åšçš„æ•ˆçއòq¶ä¸é«˜ï¼Œä½†æ˜¯ç›®å½•服务器对˜q™ç±»æœçƒ¦˜q›è¡Œäº†ä¼˜åŒ–ã€?

½W?1 部分的清å?6 中的属性文件演½CÞZº†å¦ä¸€ä¸ªåŽŸå› ï¼Œè¯¥æ–‡ä»¶ç»„åˆäº†ç”¨æˆ·å’Œè§’è‰ŒÓ€‚在真实的访问控制应用程序中åQŒæ‚¨é€šå¸¸éƒ½éœ€è¦åˆ†åˆ«å®šä¹‰å’Œ¾l´æŠ¤ç”¨æˆ·å’Œè§’色信息,˜q™æ ·åšå¯ä»¥ç®€åŒ–用户库的维护。目录服务器为更æ”ÒŽˆ–更新用户信息提供了极大的灉|´»æ€§ï¼Œä¾‹å¦‚åQŒåæ˜ èŒä½å‡˜qæˆ–新聘用äh员。参è§?参考资æ–?/a> 以了解更多关于目录服务器的ä‹É用及其优点的信息ã€?/p>

LDAP 目录讄¡½®

如果希望ž®†ç”¨æˆ·ä¿¡æ¯å­˜å‚¨åœ¨ä¸€ä¸?LDAP 目录中,您需要理解一些有关目录设¾|®çš„å†…å®¹ã€‚æœ¬æ–‡åÆˆæ²¡æœ‰æä¾›å¯?LDAP 的完整介¾lï¼ˆå‚见 参考资æ–?/a>åQ‰ï¼Œè€Œæ˜¯ä»‹ç»äº†ä¸€äº›åœ¨ž®è¯•¾l“合使用 Acegi å’?LDAP 目录之前需要了解的基本概念ã€?

LDAP 目录以节ç‚ÒŽ ‘çš„åŞ式存储信息,如图 1 所½Cºï¼š


�1. LDAP 目录的树状结�/strong>
�1. LDAP 目录的树状结� src=

在图 1 中,根节点的名称ä¸?org。根节点可以ž®è£…与不同企业有关的数据。例如,本系列第 1 部分开发的刉™€ ä¸šä¼ä¸šè¢«æ˜¾½CÞZØ“ org 节点的直接子节点。该刉™€ ä¸šä¼ä¸šå…ähœ‰ä¸¤ä¸ªåäØ“ departments å’?partners 的子节点ã€?/p>

partners 子节点封装了不同¾cÕdž‹çš„合作伙伴。图 1 所½Cºçš„三个分别ä¸?customersã€?code>employees å’?suppliers。注意,˜q™ä¸‰¿Uç±»åž‹çš„合作伙伴其行ä¸ÞZ¸Žä¼ä¸š¾pȝ»Ÿç”¨æˆ·ä¸€æ —÷€‚每一¿Uç±»åž‹çš„用户所扮演的业务角色不同,因此讉K—®¾pȝ»Ÿçš„æƒåˆ©ä¹Ÿä¸åŒã€?

¾cÖM¼¼åœŽÍ¼Œdepartments 节点包含该制造业企业的不同部门的数据 —â€?例如 engineering å’?marketing 字节炏V€‚每个部门节点还包含一¾l„或多组用户。在 å›?1 中,engineers ¾l„是 engineering 部门的子节点ã€?/p>

假设每个部门的子节点表示一¾l„用戗÷€‚因此,部门节点的子节点å…ähœ‰ä¸åŒçš„用æˆähˆå‘˜ã€‚例如,设计部门的所有工½E‹å¸ˆéƒ½æ˜¯ engineering 部门å†?engineers ¾l„的成员ã€?/p>

最后,注意 å›?1 ä¸?departments 节点的最后一个子节点ã€?code>specialUser æ˜¯ä¸€åç”¨æˆøP¼Œè€Œéžä¸€¾l„用戗÷€‚在目录讄¡½®ä¸­ï¼Œåƒ?alice å’?bob 之类的用户一般都包含åœ?partners 节点中。我ž®†è¿™ä¸ªç‰¹ŒDŠç”¨æˆ·åŒ…含在 departments 节点中,以此证明 Acegi 允许用户位于 LADP 目录中ä“Q何地点的灉|´»æ€§ã€‚稍后在本文中,您将了解如何配置 Acegi 以应ç”?specialUserã€?/p>

使用专有名称

LDAP 使用专有名称åQˆDNåQ‰çš„æ¦‚念来识åˆ?LDAP 树上特定的节炏V€‚每个节点具有惟一çš?DNåQŒå®ƒåŒ…含该节点完整的层次¾l“构信息。例如,å›?2 展示了图 1 中的一些节点的 DNåQ?/p>
å›?2. LDAP 目录节点的专有名¿U?/strong>
å›?2. LDAP 目录节点的专有名¿U? src=

首先åQŒæ³¨æ„å›¾ 2 中根节点çš?DN。它çš?DN ä¸?dc=orgåQŒè¿™æ˜¯ä¸Ž org 根节点相关的属性值对。每个节炚wƒ½æœ‰è‹¥òq²ä¸ªä¸Žä¹‹ç›¸å…³çš„属性ã€?code>dc 属性代è¡?“domain component” òq¶ç”± LDAP RFC 2256 定义åQˆå‚è§?参考资æ–?/a> 中有兛_®˜æ–?RFC 文档的链接)åQŒLDAP 目录中的根节炚w€šå¸¸è¡¨ç¤ºä¸ÞZ¸€ä¸ªåŸŸ¾l„äšgã€?/p>

每个 LDAP 属性是ç”?RFC 定义的。LDAP 允许使用多个属性创å»ÞZ¸€ä¸?DNåQŒä½†æ˜¯æœ¬æ–‡çš„½CÞZ¾‹åªä‹É用了以下 4 个属性:

  • dcåQˆåŸŸ¾l„äšgåQ?
  • oåQˆç»„¾l‡ï¼‰
  • ouåQˆç»„¾l‡å•元)
  • uidåQˆç”¨æˆ?IDåQ?

½CÞZ¾‹ä½¿ç”¨ dc 表示域,ç”?o 表示¾l„织名称åQ?code>ou 表示¾l„织的不同单元,è€?uid 表示用户ã€?/p>

ç”׃ºŽ org 是根节点åQŒå…¶ DN 只需指定自èín的名¿UŽÍ¼ˆdc=orgåQ‰ã€‚比较一下,manufacturingEnterprise 节点çš?DN æ˜?o=manufacturingEnterprise,dc=org。当向下¿UÕdŠ¨èŠ‚ç‚¹æ ‘æ—¶åQŒæ¯ä¸ªçˆ¶èŠ‚ç‚¹çš?DN 被包含在其子节点çš?DN 中ã€?

ž®†å±žæ€§åˆ†¾l?/span>

LDAP ž®†ç›¸å…³çš„å±žæ€§ç±»åž‹åˆ†åˆ°å¯¹è±¡ç±»ä¸­ã€‚ä¾‹å¦‚ï¼ŒåäØ“ organizationalPerson 的对象类所包含的属性定义了在组¾l‡å†…工作的äh员(例如åQŒèŒ¿U°ã€å¸¸ç”¨åã€é‚®å¯„地址½{‰ç­‰åQ‰ã€?

对象¾cÖM‹É用ç‘ô承特性,˜q™æ„å‘³ç€ LDAP 定义了基¾cÀL¥ä¿å­˜å¸¸ç”¨å±žæ€§ã€‚然后子¾cÕd†å¯¹åŸº¾c»è¿›è¡Œæ‰©å±•,使用其定义的属性。LDAP 目录中的单个节点可以使用若干个对象类åQšæœ¬æ–‡çš„½CÞZ¾‹ä½¿ç”¨äº†ä»¥ä¸‹å‡ ä¸ªå¯¹è±¡ç±»åQ?

  • top 对象¾cÀL˜¯ LDAP 中所有对象类的基¾c…R€?br />
  • 当其他对象类都不适合某个对象æ—Óž¼Œž®†ä‹Éç”?domain 对象¾c…R€‚它定义了一¾l„属性,ä»ÖM½•一个属性都可以用来指定一个对象。其 dc 属性是强制性的ã€?br />
  • organization 对象¾c»è¡¨½Cºç»„¾l‡èŠ‚ç‚¹ï¼Œä¾‹å¦‚ å›?2 中的 manufacturingEnterpriseã€?br />
  • organizationalUnit 对象¾c»è¡¨½Cºç»„¾l‡å†…的单元,例如 å›?1 中的 departments 节点及其子节炏V€?

  • groupOfNames 对象¾c»è¡¨½CÞZ¸€¾l„名¿UŽÍ¼Œä¾‹å¦‚某部门职员的名称。它å…ähœ‰ä¸€ä¸?member 属性,该属性包含一个用户列表ã€?a cmimpressionsent="1">å›?1 中所有的¾l„节点(例如 engineers 节点åQ‰ä‹Éç”?member 属性指定该¾l„的成员。而且åQŒç¤ºä¾‹ä‹Éç”?groupOfNames 对象¾cȝš„ ouåQˆç»„¾l‡å•元)属性指定组用户的业务角艌Ӏ?br />
  • organizationalPerson 对象¾c»è¡¨½Cºç»„¾l‡å†…某个职员åQˆä¾‹å¦?å›?1 中的 alice 节点åQ‰ã€?




回页�/strong>


使用 LDAP 服务�/span>

在真实的应用½E‹åºä¸­ï¼Œé€šå¸¸ž®†æœ‰å…³ç³»¾lŸç”¨æˆïLš„大量信息托管在一ä¸?LDAP 目录中。例如,ž®†å­˜å‚¨æ¯ä¸ªç”¨æˆïLš„用户名、密码、职¿U°ã€è”¾pÀL–¹å¼å’Œå·¥èµ„ä¿¡æ¯ã€‚äØ“½Ž€å•è“v见,下面的例子将只向您展½Cºå¦‚何保存用户名和密码ã€?

如前所˜qŽÍ¼Œ½CÞZ¾‹ä½¿ç”¨ ApacheDSåQˆä¸€¿Uå¼€æºçš„ LDAP 目录服务器)演示äº?Acegi 是如何ä‹Éç”?LDAP 目录的。示例还使用了一个开源的 LDAP å®¢æˆ·æœºï¼ˆåäØ“ JXploreråQ‰æ‰§è¡Œç®€å•的目录操作åQŒä¾‹å¦‚将信息托管åœ?ApacheDS 上。参è§?参考资æ–?/a> 以下è½?ApacheDS、JXplorer òq¶äº†è§£æ›´å¤šæœ‰å…³ä¸¤è€…协作的信息ã€?

�ApacheDS 创徏一个根节点

要创å»?å›?1 所½Cºçš„节点树,必须首先åœ?ApacheDS 中创å»ÞZ¸€ä¸ªæ ¹èŠ‚ç‚¹ org。ApacheDS 为此提供了一ä¸?XML 配置文äšg。XML 配置文äšg定义了一¾l„可˜q›è¡Œé…ç½®çš?beanåQŒä»Žè€Œæ ¹æ®åº”用程序的需求定制目录服务器的行为。本文只解释创徏根节ç‚ÒŽ‰€éœ€çš„配¾|®ã€?/p>

可以åœ?ApacheDS 安装中的 conf æ–‡äšgå¤Òމ¾åˆ°åä¸?server.xml çš?XML 配置文äšg。打开文äšg后,会发现很å¤?bean 配置¾cÖM¼¼äº?Acegi 的过滤器配置。查扑֐ä¸?examplePartitionsConfiguration çš?bean。该 bean 控制 ApacheDS 上的分区。当创徏新的根节ç‚ÒŽ—¶åQŒå®žé™…上ž®†åœ¨ LDAP 目录上创å»ÞZ¸€ä¸ªæ–°çš„分区ã€?/p>

¾~–辑 examplePartitionConfiguration bean 以创å»?org 根节点,如清å?1 所½Cºï¼š


清单 1. ¾~–辑模式çš?examplePartitionConfiguration bean 配置
                        <bean id="examplePartitionConfiguration" class=
            "org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration"
            >
            <property name="suffix"><value>dc=org</value></property>
            <property name="contextEntry">
            <value>
            objectClass: top
            objectClass: domain
            dc: org
            </value>
            </property>
            <!-- Other properties of the examplePartitionConfiguration bean, which you don't
            need to edit. -->
            </bean>
            

清单 1 ¾~–辑äº?examplePartitionConfiguration bean 的两个属性:

  • 一个属性名ä¸?suffixåQŒå®ƒå®šä¹‰æ ÒŽ¡ç›®çš„ DNã€?br />
  • 另一个属性名ä¸?contextEntryåQŒå®šä¹?org 节点ž®†ä‹É用的对象¾c…R€‚注意,org 根节点ä‹É用两个对象类åQ?code>top å’?domainã€?

本文çš?源代码下è½?/a> 部分包含了编辑模式的 server.xml æ–‡äšg。如果希望ç‘ô¾l­å­¦ä¹ æœ¬½CÞZ¾‹åQŒè¯·ž®?server.xml æ–‡äšg从源代码中复制到您的 ApacheDS 安装目录中的正确位置åQŒå³ conf æ–‡äšg夏V€?/p>

å›?3 所½Cºçš„屏幕截图展示了在 ApacheDS 中创建根节点后,JXplorer 是如何显½Cø™¯¥æ ¹èŠ‚ç‚¹çš„åQ?/p>
å›?3. JXplorer 昄¡¤ºæ ¹èŠ‚ç‚?/strong>
å›?3. JXplorer 昄¡¤ºæ ¹èŠ‚ç‚? src=

填充服务�/span>

讄¡½® LDAP 服务器的下一步是使用用户和组信息填充服务器。您可以使用 JXplorer åœ?ApacheDS 中逐个创徏节点åQŒä½†æ˜¯ä‹Éç”?LDAP Data Interchange Format (LDIF) 填充服务器会更加方便。LDIF 是可被大多数 LDAP 实现识别的常见格式。developerWorks 文章很好åœîC»‹¾läº† LDIF æ–‡äšg的内容,因此本文ž®†ä¸å†åšè¯¦ç»†è¯´æ˜Žã€‚(参见 参考资æ–?/a> 中有å…?LDIF 的详¾l†èµ„料。)

您可以在 源代码下è½?/a> 部分查看 LDIF æ–‡äšgåQŒå®ƒè¡¨ç¤º å›?1 所½Cºçš„用户和部门。您可以使用 JXplorer ž®?LDIF æ–‡äšg导入åˆ?ApacheDS。要导入 LDIF æ–‡äšgåQŒåœ¨ JXplorer 中ä‹Éç”?LDIF 菜单åQŒå¦‚å›?4 所½Cºï¼š


å›?4. ž®?LDIF æ–‡äšg导入åˆ?ApacheDS
å›?4. ž®?LDIF æ–‡äšg导入åˆ?ApacheDS

ž®?LDIF æ–‡äšg导入åˆ?ApacheDS 之后åQŒJXplorer ž®†æ˜¾½Cºç”¨æˆ¯‚Š‚ç‚¹å’Œéƒ¨é—¨èŠ‚ç‚¹æ ‘ï¼Œå¦?å›?1 所½Cºã€‚现在您可以开始配¾|?AcegiåQŒä‹É其能够与您的 LDAP 服务器通信ã€?/p>



回页�/strong>


�LDAP 实现配置 Acegi

回想一下第 1 部分åQŒå…¶ä¸?Acegi 使用íw«ä†¾éªŒè¯å¤„理˜q‡æ×o器(Authentication Processing FilteråQŒAPFåQ‰è¿›è¡Œèín份验证。APF 执行所有后端èín份验证处理ä“Q务,例如从客æˆähœºè¯äh±‚中提取用户名和密码,从后端用户库è¯Õd–用户参数åQŒä»¥åŠä‹É用这些信息对用户˜q›è¡Œíw«ä†¾éªŒè¯ã€?/p>

您在½W?1 éƒ¨åˆ†ä¸­äØ“å±žæ€§æ–‡ä»¶å®žçŽ°é…¾|®äº† APFåQŒçŽ°åœ¨æ‚¨å·²å°†ç”¨æˆ·åº“å­˜å‚¨åœ¨ LDAP 目录中,因此必须使用不同的方式配¾|®è¿‡æ»¤å™¨æ¥å’Œ LDAP 目录˜q›è¡Œé€šä¿¡ã€‚首先看一下清å?2åQŒå®ƒå±•示了在½W?1 部分中的 “Authentication Processing Filter” 一节中如何为属性文件实现配¾|?APF ˜q‡æ×o器:


清单 2. 为属性文仉™…¾|?APF
                        <bean id="authenticationProcessingFilter"
            class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="authenticationFailureUrl"
            value="/login.jsp?login_error=1" />
            <property name="defaultTargetUrl"
            value="/index.jsp" />
            <property name="filterProcessesUrl"
            value="/j_acegi_security_check" />
            </bean>
            

查看一下清å?2åQŒæ‚¨æ›„¡»ä¸?APF 提供äº?4 个参数。您只需åœ?LDAP 服务器中为存储重新配¾|®ç¬¬ä¸€ä¸ªå‚敎ͼˆauthenticationManageråQ‰å³å¯ã€‚其他三个参æ•îC¿æŒä¸å˜ã€?/p>

配置íw«ä†¾éªŒè¯½Ž¡ç†å™?/span>

清单 3 展示了如何配¾|?Acegi çš„èín份验证管理器åQŒä»¥å®žçްä¸?LDAP 服务器的通信åQ?/p>
清单 3. ä¸?LDAP 配置 Acegi çš„èín份验证管理器
                        <bean id="authenticationManager"
            class="org.acegisecurity.providers.ProviderManager">
            <property name="providers">
            <list>
            <ref local="ldapAuthenticationProvider" />
            </list>
            </property>
            </bean>
            

在清å?3 中,org.acegisecurity.providers.ProviderManager 是一个管理器¾c»ï¼Œå®ƒç®¡ç?Acegi çš„èín份验证过½E‹ã€‚äØ“æ­¤ï¼Œíw«ä†¾éªŒè¯½Ž¡ç†å™¨éœ€è¦ä¸€ä¸ªæˆ–多个íw«ä†¾éªŒè¯æä¾›è€…。您可以使用½Ž¡ç†å™?bean 的提供者属性来配置一个或多个提供者。清å?3 只包含了一个提供者,å?LDAP íw«ä†¾éªŒè¯æä¾›è€…ã€?

LDAP íw«ä†¾éªŒè¯æä¾›è€…处理所有与后端 LDAP 目录的通信。您必须对其˜q›è¡Œé…ç½®åQŒä¸‹ä¸€èŠ‚å†…å®¹å°†è®¨è®ºè¯¥ä¸»é¢˜ã€?

配置 LDAP íw«ä†¾éªŒè¯æä¾›è€?/span>

清单 4 展示äº?LDAP íw«ä†¾éªŒè¯æä¾›è€…的配置åQ?


清单 4. 配置 LDAP íw«ä†¾éªŒè¯æä¾›è€?/strong>
                        <bean id="ldapAuthenticationProvider"
            class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
            <constructor-arg><ref local="authenticator"/></constructor-arg>
            <constructor-arg><ref local="populator"/></constructor-arg>
            </bean>
            

注意 LDAP íw«ä†¾éªŒè¯æä¾›è€…类的名¿UîCØ“ org.acegisecurity.providers.ldap.LdapAuthenticationProvider 。其构造函数包含两个参敎ͼŒä½¿ç”¨ä¸¤ä¸ª <constructor-arg> 标记的åŞ式,如清å?4 所½Cºã€?/p>

LdapAuthenticationProvider 构造函数的½W¬ä¸€ä¸ªå‚数是 authenticatoråQŒè¯¥å‚数通过‹‚€æŸ¥ç”¨æˆïLš„用户名和密码å¯?LDAP 目录的用戯‚¿›è¡Œèín份验证。完成èín份验证后åQŒç¬¬äºŒä¸ªå‚æ•° populator ž®†ä»Ž LDAP 目录中检索有兌™¯¥ç”¨æˆ·çš„访问权限(或业务角è‰ÔŒ¼‰ä¿¡æ¯ã€?

以下ž®èŠ‚ž®†å‘您展½Cºå¦‚何配¾|®éªŒè¯å™¨å’Œå¡«å……器 beanã€?





回页�/strong>


配置验证�/span>

authenticator bean ž®†æ£€æŸ¥å…·æœ‰ç»™å®šç”¨æˆ·åå’Œå¯†ç çš„用户是否存在äº?LDAP 目录中。Acegi 提供了名ä¸?org.acegisecurity.providers.ldap.authenticator.BindAuthenticator 的验证器¾c»ï¼Œå®ƒå°†æ‰§è¡ŒéªŒè¯ç”¨æˆ·åå’Œå¯†ç æ‰€éœ€çš„功能ã€?/p>

配置 authenticator beanåQŒå¦‚清单 5 所½Cºï¼š


清单 5. 配置验证�bean
                        <bean id="authenticator"
            class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
            <constructor-arg><ref local="initialDirContextFactory"/></constructor-arg>
            <property name="userDnPatterns">
            <list>
            <value>uid={0},ou=employees,ou=partners</value>
            <value>uid={0},ou=customers,ou=partners</value>
            <value>uid={0},ou=suppliers,ou=partners</value>
            </list>
            </property>
            <property name="userSearch"><ref local="userSearch"/></property>
            </bean>
            

在清å?5 中,BindAuthenticator 构造函数具有一个参敎ͼŒä½¿ç”¨ <constructor-arg> 标记的åŞ式。清å?5 中参数的名称ä¸?initialDirContextFactory。该参数实际上是另一ä¸?beanåQŒç¨åŽæ‚¨ž®†å­¦ä¹ å¦‚何配¾|®è¯¥ beanã€?/p>

目前为止åQŒåªçŸ¥é“ initialDirContextFactory bean çš„ä½œç”¨å°±æ˜¯äØ“½EåŽçš„æœç´¢æ“ä½œæŒ‡å®šåˆå§‹ä¸Šä¸‹æ–‡ã€‚初始上下文是一ä¸?DNåQŒå®ƒæŒ‡å®šäº?LDAP 目录内某个节炏V€‚指定初始上下文后,ž®†åœ¨è¯¥èŠ‚ç‚¹çš„å­èŠ‚ç‚¹ä¸­æ‰§è¡Œæ‰€æœ‰çš„æœçƒ¦æ“ä½œåQˆä¾‹å¦‚查扄¡‰¹å®šç”¨æˆøP¼‰ã€?/p>

例如åQŒå›žåˆ?å›?2 中查çœ?partners 节点åQŒå®ƒçš?DN æ˜?ou=partners,o=manufacturingEnterprise,dc=org。如果将 partners 节点指定为初始上下文åQŒAcegi ž®†åªåœ?partners 节点的子节点中查扄¡”¨æˆ—÷€?

指定 DN 模式

除配¾|?BindAuthenticator 构造函数外åQŒè¿˜å¿…须配置 authenticator bean 的两个属性(清单 5 中的两个 <property> 标记åQ‰ã€?/p>

½W¬ä¸€ä¸?<property> 标记定义了一ä¸?userDnPatterns 属性,它封装了一个或多个 DN 模式列表ã€?em>DN 模式 指定了一¾l„具有类似特性的 LDAP 节点åQˆä¾‹å¦?å›?2 所½Cºçš„ employees 节点的所有子节点åQ‰ã€?/p>

Acegi çš„èín份验证器ä»?authenticator bean çš?userDnPatterns 属性中配置的每ä¸?DN 模式构造了一ä¸?DN。例如,查看 清单 5 中配¾|®çš„½W¬ä¸€ä¸ªæ¨¡å¼ï¼Œå?uid={0},ou=employees,ou=partners。在˜q›è¡Œíw«ä†¾éªŒè¯çš„æ—¶å€™ï¼Œauthenticator bean 使用用户提供的用户名åQˆæ¯”å¦?aliceåQ‰æ›¿æ¢äº† {0}。ä‹É用用户名取代äº?{0} 之后åQŒDN 模式ž®†å˜ä¸ºç›¸å¯?DNåQˆRDNåQ?code>uid=alice,ou=employees,ou=partnersåQŒå®ƒéœ€è¦ä¸€ä¸ªåˆå§‹ä¸Šä¸‹æ–‡æ‰èƒ½æˆäØ“ DNã€?/p>

例如åQŒæŸ¥çœ?å›?2 中的 alice's 条目。该条目æ˜?employees 节点的第一个子节点。它çš?DN æ˜?uid=alice,ou=employees,ou=partners,o=manufacturingEnterprise, dc=org。如果ä‹Éç”?o=manufacturingEnterprise,dc=org ä½œäØ“åˆå§‹ä¸Šä¸‹æ–‡åÆˆž®†å…¶æ·ÕdŠ åˆ?RDN uid=alice,ou=employees,ou=partners 之后åQŒå°†èŽ·å¾— alice çš?DNã€?/p>

使用˜q™ç§æ–ÒŽ³•通过 DN 模式构徏了用æˆïLš„ DN 后,authenticator ž®†æŠŠ DN 和用户密码发送到 LDAP 目录。目录将‹‚€æŸ¥è¯¥ DN 是否å…ähœ‰æ­£ç¡®çš„密码。如果有的话åQŒç”¨æˆ·å°±å¯ä»¥é€šè¿‡íw«ä†¾éªŒè¯ã€‚这个过½E‹åœ¨ LDAP 术语中被¿UîCØ“ bind íw«ä†¾éªŒè¯ã€‚LDAP ˜q˜æä¾›äº†å…¶ä»–¾cÕdž‹çš„èín份验证机åˆÓž¼Œä½†æ˜¯æœ¬æ–‡çš„示例只使用äº?bind íw«ä†¾éªŒè¯ã€?/p>

å¦‚æžœç›®å½•ä¸­åÆˆæ²¡æœ‰½W¬ä¸€ä¸?DN 模式创徏çš?DNåQ?code>authenticator bean ž®è¯•使用列表中配¾|®çš„½W¬äºŒä¸?DN 模式。依此类推,authenticator bean ž®†å°è¯•所有的 DN æ¨¡å¼æ¥äØ“˜q›è¡Œíw«ä†¾éªŒè¯çš„用æˆähž„造正¼‹®çš„用户 DNã€?/p>

搜烦˜q‡æ×oå™?/span>

回想一下较早的章节 “LDAP 目录讄¡½®”åQŒæˆ‘在将用户信息存储åˆ?LDAP 目录时添加了一点灵‹zÀL€§ã€‚方法是åœ?å›?1 所½Cºçš„ departments 节点内创å»ÞZ¸€ä¸ªç‰¹å®šç”¨æˆøP¼ˆspecialUseråQ‰ã€?/p>

如果试图使用 清单 5 中配¾|®çš„ä»ÖM½•一¿U?DN 模式创徏特定用户çš?DNåQŒæ‚¨ä¼šå‘现没有一¿U?DN 模式可用。因此,当用户尝试登录时åQŒAcegi çš?authenticator bean ž®†ä¸èƒ½å¤Ÿæž„造正¼‹®çš„ DNåQŒä»Žè€Œæ— æ³•对该用戯‚¿›è¡Œèín份验证ã€?/p>

通过允许您指定搜索过滤器åQŒAcegi 能够处理¾cÖM¼¼çš„特ŒDŠæƒ…å†üc€‚èín份验证器 bean 使用搜烦˜q‡æ×o器查找不能够通过 DN 模式构é€?DN ˜q›è¡Œíw«ä†¾éªŒè¯çš„用戗÷€?

清单 5 中的½W¬äºŒä¸?<property> 标记å…ähœ‰ä¸€ä¸?<ref> 子标讎ͼŒå®ƒå¼•用名ä¸?userSearch çš?beanã€?code>userSearch bean 指定搜烦查询。清å?6 展示了如何配¾|?userSearch bean æ¥å¤„ç†ç‰¹å®šç”¨æˆøP¼š


清单 6. 配置搜烦查询以搜索特定用�/strong>
                        <bean id="userSearch"
            class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
            <constructor-arg>
            <value>ou=departments</value>
            </constructor-arg>
            <constructor-arg>
            <value>(uid={0})</value>
            </constructor-arg>
            <constructor-arg>
            <ref local="initialDirContextFactory" />
            </constructor-arg>
            <property name="searchSubtree">
            <value>true</value>
            </property>
            </bean>
            

搜烦查询的参�/strong>

清单 6 展示äº?userSearch bean æ˜?org.acegisecurity.ldap.search.FilterBasedLdapUserSearch ¾cȝš„一个实例,该类的构造函数具有三个参数。第一个参数指å®?authenticator 在哪个节点中搜烦用户。第一个参数的å€égØ“ ou=departmentsåQŒè¯¥å€¼æ˜¯ä¸€ä¸?RDNåQŒæŒ‡å®šäº† å›?2 所½Cºçš„ departments 节点ã€?/p>

½W¬äºŒä¸ªå‚æ•?(uid={0}) 指定了一个搜索过滤器。由于ä‹Éç”?uid å±žæ€§æŒ‡å®šç”¨æˆøP¼Œå› æ­¤å¯ä»¥é€šè¿‡æŸ¥æ‰¾ uid 属性具有特定值的节点来查扄¡”¨æˆ—÷€‚正如您所料,花括号里面的 0 å?Acegi 表示使用˜q›è¡Œíw«ä†¾éªŒè¯çš„用æˆïLš„ç”¨æˆ·åï¼ˆæœ¬ä¾‹ä¸­äØ“ specialUseråQ‰æ›¿æ?{0}ã€?

½W¬ä¸‰ä¸ªå‚数是对讨è®?清单 5 中的 BindAuthenticator 构造函数时引入的相同初始上下文的引用。回想一下,当指定了初始上下文后åQŒç¨åŽå°†åœ¨è¯¥åˆå§‹ä¸Šä¸‹æ–‡èŠ‚ç‚¹çš„å­èŠ‚ç‚¹å†…˜q›è¡Œæ‰€æœ‰çš„æœçƒ¦æ“ä½œã€‚注意,应将指定ä¸?清单 5 中第一个参敎ͼˆou=departmentsåQ‰çš„值的 RDN 前加到初始上下文ã€?/p>

除了˜q™ä¸‰ä¸ªæž„造器参数åQŒæ¸…å?6 所½Cºçš„ userSearch bean ˜q˜å…·æœ‰ä¸€ä¸ªåä¸?searchSubtree çš„å±žæ€§ã€‚å¦‚æžœå°†å…¶å€¼æŒ‡å®šäØ“ trueåQŒæœç´¢æ“ä½œå°†åŒ…括节点的子树(åÏx‰€æœ‰å­èŠ‚ç‚¹ã€å­™èŠ‚ç‚¹ã€å­™èŠ‚ç‚¹çš„å­èŠ‚ç‚¹½{‰ï¼‰åQŒè¯¥èŠ‚ç‚¹è¢«æŒ‡å®šäØ“æž„é€ å‡½æ•°çš„½W¬ä¸€ä¸ªå‚数的倹{€?

authenticator bean 的配¾|®å®ŒæˆåŽåQŒä¸‹ä¸€æ­¥å°†æŸ¥çœ‹ populator bean 的配¾|®ï¼Œå¦?清单 4 所½Cºã€?/p>



回页�/strong>


配置 populator

populator bean ž®†è¯»å–å·²¾lé€šè¿‡ authenticator bean íw«ä†¾éªŒè¯çš„用æˆïLš„业务角色。清å?7 展示 populator bean çš?XML 配置åQ?/p>
清单 7. populator bean �XML 配置
                        <bean id="populator"
            class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
            <constructor-arg>
            <ref local="initialDirContextFactory"/>
            </constructor-arg>
            <constructor-arg>
            <value>ou=departments</value>
            </constructor-arg>
            <property name="groupRoleAttribute">
            <value>ou</value>
            </property>
            <property name="searchSubtree">
            <value>true</value>
            </property>
            </bean>
            

在清å?7 中,populator bean 的构造函数包æ‹?2 个参敎ͼŒä»¥åŠä¸€ä¸?groupRoleAttribute 属性。构造函数的½W¬ä¸€ä¸ªå‚数指定了 populator bean 用来è¯Õd–¾lè¿‡éªŒè¯ç”¨æˆ·çš„ä¸šåŠ¡è§’è‰²çš„åˆå§‹ä¸Šä¸‹æ–‡ã€‚åÆˆä¸å¼ºåˆ¶è¦æ±?authenticator å’?populator bean ä½¿ç”¨ç›¸åŒçš„åˆå§‹ä¸Šä¸‹æ–‡ã€‚æ‚¨å¯ä»¥ä¸ø™¿™ä¸¤è€…分别配¾|®ä¸€ä¸ªåˆå§‹ä¸Šä¸‹æ–‡ã€?/p>

½W¬äºŒä¸ªæž„造函数参数指定了 populator 前加到初始上下文çš?RDN。因此,RDN ¾l„成了包含组用户的节点的 DNåQŒä¾‹å¦?departments 节点ã€?/p>

populator bean çš?groupRoleAttribute 属性指定了持有¾l„成员业务角色数据的属性。回æƒ?讄¡½® LDAP 目录 一节中åQŒæ‚¨ž®†æ¯¾l„用æˆïLš„业务角色信息存储在名ä¸?ou 的属性中。然后将 ou 讄¡½®ä¸?groupRoleAttribute 属性的å€û|¼Œå¦?清单 7 所½Cºã€?

如您所料,populator bean ž®†æœç´¢æ•´ä¸?LDAP 目录来查扄¡»˜q‡éªŒè¯çš„用户所属的¾l„节炏V€‚然后读取组节点çš?ou 属性的å€û|¼ŒèŽ·å–ç”¨æˆ·¾lè¿‡æŽˆæƒçš„业务角艌Ӏ?/p>

˜q™æ ·ž®±å®Œæˆäº† populator bean 的配¾|®ã€‚ç›®å‰äØ“æ­¢ï¼Œæˆ‘ä»¬åœ¨ä¸‰ä¸ªä½¾|®ä‹É用了初始上下文:清单 5ã€?a cmimpressionsent="1">清单 6 å’?清单 7。接下来ž®†äº†è§£å¦‚何配¾|®åˆå§‹ä¸Šä¸‹æ–‡ã€?/p>

配置初始上下�/span>

清单 8 展示了在 Acegi 中配¾|®åˆå§‹ä¸Šä¸‹æ–‡çš„过½E‹ï¼š


清单 8. 初始上下文的 XML 配置
                        <bean id="initialDirContextFactory"
            class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
            <constructor-arg value="ldap://localhost:389/o=manufacturingEnterprise,dc=org"/>
            <property name="managerDn">
            <value>cn=manager,o=manufacturingEnterprise,dc=org</value>
            </property>
            <property name="managerPassword">
            <value>secret</value>
            </property>
            </bean>
            

清单 8 ä¸?Acegi 的初始上下文¾cȝš„名称ä¸?org.acegisecurity.ldap.DefaultInitialDirContextFactoryåQŒè¿™æ˜?Acegi 包含的工厂类。Acegi 在内部ä‹É用该¾cÀLž„造其他处理目录操作(例如在整个目录中搜烦åQ‰çš„¾cȝš„对象。当配置初始上下文工厂时åQŒå¿…™åÀLŒ‡å®šä»¥ä¸‹å†…容:

  • ž®†æ‚¨çš?LDAP 目录和根目录节点的网¾lœåœ°å€æŒ‡å®šä¸ºæž„造函数的参数。在初始上下文配¾|®çš„节点ž®†ä½œä¸ºæ ¹èŠ‚ç‚¹ã€‚å°±æ˜¯è¯´æ‰€æœ‰åŽ¾l­æ“ä½œï¼ˆä¾‹å¦‚ searchåQ‰éƒ½ž®†åœ¨æ ¹èŠ‚ç‚¹å®šä¹‰çš„å­æ ‘ä¸­æ‰§è¡Œã€?br />
  • ž®?DN å’Œå¯†ç åˆ†åˆ«å®šä¹‰äØ“ managerDn å’?managerPassword 属性。在执行ä»ÖM½•搜烦操作之前åQŒAcegi 必须使用目录服务器对 DN 和密码进行èín份验证ã€?

您已¾läº†è§£äº†å¦‚何ž®†ç”¨æˆ·åº“托管åœ?LDAP 目录中,以及如何配置 Acegi 来ä‹É用来è‡?LDAP 目录的信息对用户˜q›è¡Œíw«ä†¾éªŒè¯ã€‚下一节将˜q›ä¸€æ­¥ä»‹¾l?Acegi çš„èín份验证处理过滤器åQŒäº†è§£æ–°é…ç½®çš?bean 是如何管理èín份验证过½E‹çš„ã€?/p>



回页�/strong>


íw«ä†¾éªŒè¯å’ŒæŽˆæ?/span>

APF 配置完成后,ž®†èƒ½å¤Ÿä¸Ž LDAP 目录˜q›è¡Œé€šä¿¡æ¥å¯¹ç”¨æˆ·˜q›è¡Œíw«ä†¾éªŒè¯ã€‚如果您阅读˜q‡ç¬¬ 1 部分åQŒé‚£ä¹ˆå¯¹ä¸Žç›®å½•通信˜q‡ç¨‹ä¸?APF 执行的一些步骤不会感到陌生,我在½W?1 部分中向您展½CÞZº†˜q‡æ×o器如何ä‹É用不同的服务˜q›è¡Œç”¨æˆ·íw«ä†¾éªŒè¯ã€‚图 5 所½Cºçš„序列表与您在 ½W?1 部分å›?3 看到的非常类ä¼û|¼š


å›?5. APF 对一å?LDAP 用户˜q›è¡Œíw«ä†¾éªŒè¯
å›?5. APF 对一å?LDAP 用户˜q›è¡Œíw«ä†¾éªŒè¯

无论 APF 使用属性文件进行内部的íw«ä†¾éªŒè¯˜q˜æ˜¯ä¸?LDAP 服务器进行通信åQŒæ­¥éª?1 到步éª?9 与第 1 部分是相同的。这里简单描˜qîCº†å‰?9 个步骤,您可以从步骤 10 开始ç‘ô¾l­å­¦ä¹ ç‰¹å®šäºŽ LDAP 的事ä»Óž¼š

  1. ˜q‡æ×o器链前面的过滤器ž®†è¯·æ±‚、响应和˜q‡æ×o器链对象传递给 APFã€?br />
  2. APF 使用取自è¯äh±‚对象的用户名、密码和其他信息创徏一个èín份验证标记ã€?br />
  3. APF ž®†èín份验证标è®îC¼ é€’ç»™íw«ä†¾éªŒè¯½Ž¡ç†å™¨ã€?br />
  4. íw«ä†¾éªŒè¯½Ž¡ç†å™¨å¯èƒ½åŒ…含一个或多个íw«ä†¾éªŒè¯æä¾›è€…。每个提供者恰好支持一¿Uèín份验证类型。管理器ž®†æ£€æŸ¥å“ªä¸€¿Uæä¾›è€…支持从 APF 接收到的íw«ä†¾éªŒè¯æ ‡è®°ã€?

  5. íw«ä†¾éªŒè¯½Ž¡ç†å™¨å°†íw«ä†¾éªŒè¯æ ‡è®°ä¼ é€’给适合该类型èín份验证的提供者ã€?

  6. íw«ä†¾éªŒè¯æä¾›è€…从íw«ä†¾éªŒè¯æ ‡è®°ä¸­æå–用户名òq¶å°†å…¶ä¼ é€’åˆ°åäØ“ user cache service 的服务。Acegi ¾~“存了已¾lè¿›è¡Œè¿‡íw«ä†¾éªŒè¯çš„用戗÷€‚该用户下次ç™Õd½•æ—Óž¼ŒAcegi 可以从缓存中加蝲他或她的详细信息åQˆæ¯”如用户名、密码和权限åQ‰ï¼Œè€Œä¸æ˜¯ä»ŽåŽç«¯æ•°æ®å­˜å‚¨ä¸­è¯»å–数据。这¿Uæ–¹æ³•ä‹É得性能得到了改善ã€?br />
  7. user cache service ‹‚€æŸ¥ç”¨æˆïLš„详细信息是否存在于缓存中ã€?br />
  8. user cache service ž®†ç”¨æˆïLš„详细信息˜q”回¾l™èín份验证提供者。如果缓存不包含用户详细信息åQŒåˆ™˜q”回 nullã€?br />
  9. íw«ä†¾éªŒè¯æä¾›è€…检查缓存服务返回的是用æˆïLš„详细信息˜q˜æ˜¯ nullã€?br />
  10. 从这里开始,íw«ä†¾éªŒè¯å¤„理ž®†ç‰¹å®šäºŽ LDAPã€?/strong> 如果¾~“å­˜˜q”回 nullåQŒLDAP íw«ä†¾éªŒè¯æä¾›è€…将把用户名åQˆåœ¨æ­¥éª¤ 6 中提取的åQ‰å’Œå¯†ç ä¼ é€’ç»™ 清单 5 中配¾|®çš„ authenticator beanã€?br />
  11. authenticator ž®†ä‹É用在 清单 5 çš?userDnPatterns 属性中配置çš?DN 模式创徏用户 DN。通过从一ä¸?DN 模式中创å»ÞZ¸€ä¸?DNåQŒç„¶åŽå°†è¯?DN 和用户密码(从用戯‚¯·æ±‚中获得åQ‰å‘送到 LDAP 目录åQŒå®ƒž®†é€ä¸€ž®è¯•所有可用的 DN 模式。LDAP 目录ž®†æ£€æŸ¥è¯¥ DN 是否存在以及密码是否正确。如果其中ä“Q何一ä¸?DN 模式可行的话åQŒç”¨æˆ¯‚¢«¾l‘定åˆ?LDAP 目录中,authenticator ž®†ç‘ô¾l­æ‰§è¡Œæ­¥éª?15ã€?

  12. 如果ä»ÖM½•一¿U?DN 模式都不能工作的话(˜q™æ„å‘³ç€åœ?DN 模式指定的ä“Q何位¾|®éƒ½ä¸å­˜åœ¨ä‹É用给定密码的用户åQ‰ï¼Œauthenticator æ ÒŽ® 清单 6 配置的搜索查询在 LDAP 目录中搜索用戗÷€‚如æž?LDAP 目录没有扑ֈ°ç”¨æˆ·åQŒé‚£ä¹ˆèín份验证以å¤ÞpÓ|告终ã€?br />
  13. 如果 LDAP 目录查找åˆîCº†ç”¨æˆ·åQŒå®ƒž®†ç”¨æˆïLš„ DN ˜q”回åˆ?authenticatorã€?br />
  14. authenticator ž®†ç”¨æˆ?DN 和密码发送到 LDAP 目录来检查用户密码是否正¼‹®ã€‚如æž?LDAP 目录发现用户密码是正¼‹®çš„åQŒè¯¥ç”¨æˆ·ž®†è¢«¾l‘定åˆ?LDAP 目录ã€?br />
  15. authenticator ž®†ç”¨æˆ·ä¿¡æ¯å‘送回 LDAP íw«ä†¾éªŒè¯æä¾›è€…ã€?br />
  16. LDAP íw«ä†¾éªŒè¯æä¾›è€…将控制权传递给 populator beanã€?br />
  17. populator 搜烦用户所属的¾l„ã€?br />
  18. LDAP 目录ž®†ç”¨æˆ¯‚§’色信息返回给 populatorã€?br />
  19. populator ž®†ç”¨æˆ¯‚§’色信息返回给 LDAP íw«ä†¾éªŒè¯æä¾›è€…ã€?br />
  20. LDAP íw«ä†¾éªŒè¯æä¾›è€…将用户的详¾l†ä¿¡æ¯ï¼ˆä»¥åŠç”¨æˆ·ä¸šåŠ¡è§’è‰²ä¿¡æ¯åQ‰è¿”回给 APF。用æˆïLŽ°åœ¨æˆåŠŸè¿›è¡Œäº†íw«ä†¾éªŒè¯ã€?

不论使用何种íw«ä†¾éªŒè¯æ–ÒŽ³•åQŒæœ€åŽä¸‰ä¸ªæ­¥éª¤æ˜¯ç›¸åŒçš„(步骤21ã€?1 å’?23åQ‰ã€?/p>

配置拦截�/span>

您已¾läº†è§£äº† APF 对用戯‚¿›è¡Œèín份验证的步骤。接下来是查看成功进行èín份验证的用户是否被授权访问所è¯äh±‚的资源。这™å¹ä“Q务由 Acegi 的拦截过滤器åQˆInterceptor FilteråQŒIFåQ‰å®Œæˆã€‚本节将向您展示如何配置 IF 来实现访问控制策略ã€?

回想一下在 ½W?1 部分的清å?7 中配¾|?IF 的步骤。拦截过滤器在资源和角色之间建立映射åQŒå°±æ˜¯è¯´åªæœ‰å…·å¤‡å¿…要角色的用æˆäh‰èƒ½è®¿é—®ç»™å®šèµ„æºã€‚äØ“äº†æ¼”½Cºåˆ¶é€ ä¸šä¼ä¸šä¸­ä¸åŒéƒ¨é—¨çš„业务角色åQŒæ¸…å?9 向现有的 IF 配置æ·ÕdŠ äº†å¦å¤–çš„è§’è‰²åQ?/p>
清单 9. 配置拦截˜q‡æ×oå™?/strong>
                        <bean id="filterInvocationInterceptor"
            class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="accessDecisionManager" ref="accessDecisionManager" />
            <property name="objectDefinitionSource">
            <value>
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /protected/engineering/**=ROLE_HEAD_OF_ENGINEERING
            /protected/marketing/**=ROLE_HEAD_OF_MARKETING
            /**=IS_AUTHENTICATED_ANONYMOUSLY
            </value>
            </property>
            </bean>
            

在清å?9 中,IF 包含三个参数。其中第一个和½W¬ä¸‰ä¸ªå‚æ•îC¸Ž½W?1 部分中最初配¾|®çš„参数相同。这里添加了½W¬äºŒä¸ªå‚敎ͼˆåäØ“ accessDecisionManager çš?beanåQ‰ã€?/p>

accessDecisionManager bean 负责指定授权决策。它使用清单 9 中第三个参数提供的访问控制定义来指定授权åQˆæˆ–讉K—®æŽ§åˆ¶åQ‰å†³½{–。第三个参数æ˜?objectDefinitionSourceã€?/p>

配置讉K—®å†³ç­–½Ž¡ç†å™?/span>

accessDecisionManager 军_®šæ˜¯å¦å…è®¸ä¸€ä¸ªç”¨æˆ¯‚®¿é—®æŸä¸ªèµ„源。Acegi 提供了一些访问决½{–管理器åQŒå®ƒä»¬æŒ‡å®šè®¿é—®æŽ§åˆ¶å†³½{–的方式有所不同。本文只解释了其中一¿Uè®¿é—®å†³½{–管理器的工作方式,光™…¾|®å¦‚清单 10 所½Cºï¼š


清单 10. 配置讉K—®å†³ç­–½Ž¡ç†å™?/strong>
                        <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
            <property name="decisionVoters">
            <list>
            <bean class="org.acegisecurity.vote.RoleVoter"/>
            <bean class="org.acegisecurity.vote.AuthenticatedVoter" />
            </list>
            </property>
            </bean>
            

在清å?10 中,accessDecisionManager bean æ˜?org.acegisecurity.vote.AffirmativeBased ¾cȝš„实例ã€?code>accessDecisionManager bean 只包含一个参敎ͼŒå?em>投票者(voteråQ?/em>列表ã€?/p>

åœ?Acegi 中,投票者确定是否允许某个用戯‚®¿é—®ç‰¹å®šçš„资源。当使用 accessDecisionManager 查询æ—Óž¼ŒæŠ•票者具有三个选项åQšå…è®¸è®¿é—®ï¼ˆaccess-grantedåQ‰ã€æ‹’¾lè®¿é—®ï¼ˆaccess-deniedåQ‰ï¼Œå¦‚果不确定的话则攑ּƒæŠ•票åQˆabstain from votingåQ‰ã€?/p>

不同¾cÕdž‹çš„访问决½{–管理器解释投票者决½{–çš„æ–ÒŽ³•也有所不同。清å?10 所½Cºçš„ AffirmativeBased 讉K—®å†³ç­–½Ž¡ç†å™¨å®žçŽîCº†½Ž€å•的决策逻辑åQšå¦‚æžœä“Q何投¼œ¨è€…强制执行肯定投¼œ¨ï¼Œž®†å…è®¸ç”¨æˆ¯‚®¿é—®æ‰€è¯äh±‚的资源ã€?/p>

投票者逻辑

Acegi 提供了若òq²ä¸ªæŠ•票者实现类型ã€?code>accessDecisionManager ž®†ç»˜q‡éªŒè¯çš„用户的信息(包括用户的业务角色信息)å’?objectDefinitionSource 对象传递给投票者。本文的½CÞZ¾‹ä½¿ç”¨äº†ä¸¤¿Uç±»åž‹çš„æŠ•票者,RoleVoter å’?AuthenticatedVoteråQŒå¦‚清单 10 所½Cºã€‚现在看一下每¿UæŠ•¼œ¨è€…的逻辑åQ?/p>

  • RoleVoter 只有åœ?objectDefinitionSource 对象的行中找åˆîC»¥ ROLE_ 前缀开头的角色时才˜q›è¡ŒæŠ•票。如æž?RoleVoter 没有扑ֈ°˜q™æ ·çš„行åQŒå°†æ”‘Ö¼ƒæŠ•票åQ›å¦‚果在用户业务角色中找åˆîC¸€ä¸ªåŒ¹é…çš„角色åQŒå®ƒž®†æŠ•¼œ¨ç»™å…è®¸è®‰K—®åQ›å¦‚果没有找到匹配的角色åQŒåˆ™æŠ•票¾l™æ‹’¾lè®¿é—®ã€‚在 清单 9 中,有两个角色具æœ?ROLE_ 前缀åQ?code>ROLE_HEAD_OF_ENGINEERING å’?ROLE_HEAD_OF_MARKETINGã€?br />
  • AuthenticatedVoter 只有åœ?objectDefinitionSource 对象中找到具有某个预定义角色的行时才˜q›è¡ŒæŠ•票。在 清单 9 中,有这样一行:IS_AUTHENTICATED_ANONYMOUSLY。匿名èín份验证意味着用户不能够进行èín份验证。找到该行后åQ?code>AuthenticatedVoter ž®†æ£€æŸ¥ä¸€ä¸ªåŒ¿åèín份验证的用户是否可以讉K—®æŸäº›ä¸å—保护的资源(卌™¿™äº›èµ„源没有包含在具备 ROLE_ 前缀的行中)。如æž?AuthenticatedVoter 发现所è¯äh±‚çš„èµ„æºæ˜¯ä¸å—ä¿æŠ¤çš„åÆˆä¸?objectDefinitionSource 对象允许匿名íw«ä†¾éªŒè¯çš„用戯‚®¿é—®ä¸å—保护的资源åQŒå®ƒž®†æŠ•¼œ¨ç»™å…è®¸è®‰K—®åQ›å¦åˆ™å°±æŠ•票¾l™æ‹’¾lè®¿é—®ã€?




回页�/strong>


½CÞZ¾‹åº”用½E‹åº

本文提供了一个示例应用程序,它将演示您目前掌握的 LDAP å’?Acegi 概念。LDAP-Acegi 应用½E‹åºž®†æ˜¾½CÞZ¸€ä¸ªçƒ¦å¼•页面,该页面将设计和销售文档呈现给合适的¾lè¿‡íw«ä†¾éªŒè¯çš„用戗÷€‚正如您ž®†çœ‹åˆ°çš„ä¸€æ øP¼ŒLDAP-Acegi 应用½E‹åºå…è®¸ç”¨æˆ· alice 查看设计文档åQŒåƈ允许用户 bob 查看销售文档。它˜q˜å…è®¸ç‰¹å®šç”¨æˆ·åŒæ—¶æŸ¥çœ‹è®¾è®¡å’Œé”€å”®æ–‡æ¡£ã€‚所有这些内定wƒ½æ˜¯åœ¨æœ¬æ–‡å¼€å¤´é…¾|?LDAP 目录服务器时讄¡½®çš„。立å?下蝲½CÞZ¾‹åº”用½E‹åº 来开始ä‹É用它ã€?/p>



回页�/strong>


¾l“束è¯?/span>

在本文中åQŒæ‚¨äº†è§£äº†å¦‚何将用户和业务角色信息托½Ž¡åœ¨ LDAP 目录中。您˜q˜è¯¦¾l†äº†è§£äº†é…ç½® Acegi 的方法,从而与 LDAP 目录交互实现讉K—®æŽ§åˆ¶½{–略。在本系列最后一期文章中åQŒæˆ‘ž®†å±•½Cºå¦‚何配¾|?Acegi 来保护对 Java ¾cȝš„讉K—®ã€?/p>

来自:http://www.cnblogs.com/amboyna/archive/2008/03/25/1122084.html

]]>acegi,IBMçš„Acegi Security SystemåQ?åQ?http://www.aygfsteel.com/waterjava/archive/2008/05/08/199309.html狼爱上狸狼爱上狸Thu, 08 May 2008 10:41:00 GMThttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199309.htmlhttp://www.aygfsteel.com/waterjava/comments/199309.htmlhttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199309.html#Feedback0http://www.aygfsteel.com/waterjava/comments/commentRss/199309.htmlhttp://www.aygfsteel.com/waterjava/services/trackbacks/199309.html2007 òq?5 æœ?08 æ—?/p>
˜q™ä†¾å…±åˆ†ä¸‰éƒ¨åˆ†çš„¾pÕdˆ—文章介绍äº?Acegi 安全¾pȝ»ŸåQˆAcegi Security SystemåQ‰ï¼Œå®ƒæ˜¯ç”¨äºŽ Java™ 企业应用½E‹åºçš„强大的开源安全框架。在½W¬ä¸€½‹‡æ–‡ç« ä¸­åQŒBilal Siddiqui ™åùN—®ž®†å‘您介¾l?Acegi 的架构和¾l„äšgåQŒåƈ展示如何使用它来保护一个简单的 Java 企业应用½E‹åºã€?/blockquote>

Acegi Security System 是一¿UåŠŸèƒ½å¼ºå¤§åÆˆæ˜“äºŽä½¿ç”¨çš„æ›¿ä»£æ€§æ–¹æ¡ˆï¼Œä½¿æ‚¨ä¸å¿…å†äØ“ Java 企业应用½E‹åº¾~–写大量的安全代码。虽然它专门针对使用 Spring 框架¾~–写的应用程序,但是ä»ÖM½•¾cÕdž‹çš?Java 应用½E‹åºéƒ½æ²¡æœ‰ç†ç”׃¸åŽÖM‹Éç”?Acegi。这份共分三部分的系列文章详¾l†ä»‹¾läº† AcegiåQŒåƈ展示了如何ä‹É用它保护½Ž€å•的企业应用½E‹åºä»¥åŠæ›´å¤æ‚的应用½E‹åºã€?/p>

本系列首先介¾lä¼ä¸šåº”用程序中常见的安全问题,òq¶è¯´æ˜?Acegi 如何解决˜q™äº›é—®é¢˜ã€‚您ž®†äº†è§?Acegi 的架构模型及其安全过滤器åQŒåŽè€…包含了在保护应用程序中ž®†ç”¨åˆ°çš„大多数功能。您˜q˜å°†äº†è§£åˆ°å„个过滤器如何单独˜q›è¡Œå·¥ä½œåQŒå¦‚何将它们¾l„合èµäh¥åQŒä»¥åŠè¿‡æ»¤å™¨å¦‚何在一个企业安全实çŽîC¸­ž®†å„¿UåŠŸèƒ½ä»Žå¤´åˆ°ž®‘Öœ°é“¾æŽ¥èµäh¥ã€‚本文最后通过一个样例应用程序演½CÞZº†åŸÞZºŽ URL 安全¾pȝ»Ÿçš?Acegi 实现。本¾pÕdˆ—后箋两篇文章ž®†æŽ¢½I?Acegi 的一些更高çñ”的应用,包括如何设计和托½Ž¡è®¿é—®æŽ§åˆ¶ç­–略,然后如何去配¾|?Acegi 以ä‹É用这些策略ã€?/p>

您必™å?下蝲 AcegiåQŒè¿™æ äh‰èƒ½ç¼–译本文的½CÞZ¾‹ä»£ç òq¶è¿è¡Œæœ¬æ–‡çš„æ ·ä¾‹åº”用½E‹åºã€‚还必须有作为工作站的一部分˜qè¡Œçš?Tomcat 服务器ã€?/p>

企业应用½E‹åºå®‰å…¨æ€?/span>

ç”׃ºŽä¼ä¸šå†…容½Ž¡ç†åQˆECMåQ‰åº”用程序管理存储在不同¾cÕdž‹æ•°æ®æºï¼ˆå¦‚文件系¾lŸã€å…³¾pÀL•°æ®åº“和目录服务)中的企业内容的编写和处理åQŒECM 安全性要求对˜q™äº›æ•°æ®æºçš„讉K—®˜q›è¡ŒæŽ§åˆ¶ã€‚比如,一ä¸?ECM 应用½E‹åºå¯èƒ½ä¼šæŽ§åˆ¶è¢«æŽˆæƒè¯Õd–、编辑或删除数据的对象,而这些数据和刉™€ ä¸šä¼ä¸šçš„è®¾è®¡ã€å¸‚åœø™¥é”€ã€ç”Ÿäº§ä»¥åŠè´¨é‡æŽ§åˆ¶æœ‰å…Ÿë€?/p>

在一ä¸?ECM 安全场景中,比较常见的就是通过对企业资源定位符åQˆæˆ–¾|‘络地址åQ‰åº”用安全性,从而实现访问控制。这¿Uç®€å•的安全模型被称ä¸?em>¾lŸä¸€èµ„源定位½W?/em> æˆ?URL 安全性。正如我在本文后面(以及本系列后¾l­æ–‡ç« ï¼‰æ‰€æ¼”ç¤ºçš„ä¸€æ øP¼ŒAcegi 为实çŽ?URL 安全性提供了全面的特性ã€?/p>

然而,在很多企业场景中åQŒURL 安全性还˜qœè¿œä¸å¤Ÿã€‚比如,假设一ä¸?PDF 文档包含某个刉™€ ä¸šå…¬å¸ç”Ÿäñ”的特ŒDŠäñ”品的数据。文档的一部分包含了将ç”Þp¯¥å…¬å¸çš„设计部门编辑和更新的设计数据。另一部分包含了生产经理将使用的生产数据。对于诸如此¾cȝš„场景åQŒéœ€è¦å®žçŽ°æ›´åŠ ç»†¾_’度的安全性,å¯ÒŽ–‡æ¡£çš„不同部分应用不同的访问权限ã€?/p>

本文介绍äº?Acegi 为实çŽ?URL 安全性而提供的各种功能。本¾pÕdˆ—的下一½‹‡æ–‡ç« å°†æ¼”示此框架的åŸÞZºŽæ–ÒŽ³•的安全性,它提供了对企业数据访问的更细¾_’度的控制ã€?/p>



回页�/strong>


Acegi Security System

Acegi Security System 使用安全˜q‡æ×o器来提供企业应用½E‹åºçš„èín份验证和授权服务。该框架提供了不同类型的˜q‡æ×o器,可以æ ÒŽ®åº”用½E‹åºçš„需求进行配¾|®ã€‚您ž®†åœ¨æœ¬æ–‡åŽé¢äº†è§£åˆ?安全˜q‡æ×o器的不同¾cÕdž‹åQ›çŽ°åœ¨ï¼Œåªéœ€æ³¨æ„å¯ä»¥ä¸ºå¦‚ä¸‹ä“Q务配¾|?Acegi 安全˜q‡æ×o器:

  1. 在访问一个安全资源之前提½Cºç”¨æˆïL™»å½•ã€?br />
  2. 通过‹‚€æŸ¥å®‰å…¨æ ‡è®ŽÍ¼ˆå¦‚密码)åQŒå¯¹ç”¨æˆ·˜q›è¡Œíw«ä†¾éªŒè¯ã€?br />
  3. ‹‚€æŸ¥ç»˜q‡èín份验证的用户是否å…ähœ‰è®‰K—®æŸä¸ªå®‰å…¨èµ„源的特权ã€?br />
  4. ž®†æˆåŠŸè¿›è¡Œèín份验证和授权的用户重定向到所è¯äh±‚的安全资源ã€?br />
  5. 对不具备讉K—®å®‰å…¨èµ„源ç‰ÒŽƒçš„用æˆäh˜¾½C?Access Denied ™åµé¢ã€?br />
  6. 在服务器上记录成功进行èín份验证的用户åQŒåƈ在用æˆïLš„客户æœÞZ¸Šè®„¡½®å®‰å…¨ cookie。ä‹É用该 cookie 执行下一‹Æ¡èín份验证,而无需要求用户ç™Õd½•ã€?br />
  7. ž®†èín份验证信息存储在服务器端的会话对象中åQŒä»Žè€Œå®‰å…¨åœ°˜q›è¡Œå¯¹èµ„源的后箋è¯äh±‚ã€?br />
  8. 在服务器端对象中构徏òq¶ä¿å­˜å®‰å…¨ä¿¡æ¯çš„¾~“å­˜åQŒä»Žè€Œä¼˜åŒ–性能ã€?br />
  9. 当用户退出时åQŒåˆ é™¤äؓ用户安全会话而保存的服务器端对象ã€?br />
  10. 与大量后端数据存储服务(如目录服务或关系数据库)˜q›è¡Œé€šä¿¡åQŒè¿™äº›æœåŠ¡ç”¨äºŽå­˜å‚¨ç”¨æˆïLš„安全信息å’?ECM 的访问控制策略ã€?

正如˜q™ä¸ªåˆ—表昄¡¤ºçš„é‚£æ øP¼ŒAcegi 的安全过滤器允许您执行保护企业应用程序所需的几乎ä“Q何事情ã€?/p>



回页�/strong>


架构和组�/span>

å¯?Acegi 了解­‘Šå¤šåQŒä‹É用è“v来就­‘Šç®€å•。这一节介¾l?Acegi 的组ä»Óž¼›æŽ¥ä¸‹æ¥æ‚¨ž®†äº†è§£è¯¥æ¡†æž¶å¦‚何使用反è{控制åQˆIOCåQ‰å’Œ XML 配置文äšgæ¥ç»„åˆç»„ä»¶åÆˆè¡¨ç¤ºå®ƒä»¬çš„ä¾èµ–å…³¾p…R€?

四大¾l„äšg

Acegi Security System 由四¿Uä¸»è¦ç±»åž‹çš„¾l„äšg¾l„成åQšè¿‡æ»¤å™¨ã€ç®¡ç†å™¨ã€æä¾›è€…和处理½E‹åºã€?/p>

˜q‡æ×oå™?/strong>
˜q™ç§æœ€é«˜çñ”的组件提供了常见的安全服务,如èín份验证、会话处理以及注销。我ž®†åœ¨ 本文后面的部åˆ?/a> 深入讨论˜q‡æ×o器ã€?
½Ž¡ç†å™?/strong>
˜q‡æ×o器仅是安全相兛_ŠŸèƒ½çš„é«˜çñ”抽象åQšå®žé™…上要ä‹É用管理器和提供者实现èín份验证处理和注销服务。管理器½Ž¡ç†ç”׃¸åŒæä¾›è€…提供的较低¾U§çš„安全服务ã€?
提供�/strong>
有大量的提供者可用于和不同类型的数据存储服务通信åQŒä¾‹å¦‚目录服务、关¾pÀL•°æ®åº“或简单的内存中的对象。这意味着您可以将用户库和讉K—®æŽ§åˆ¶åè®®å­˜å‚¨åœ¨ä“Q何一¿Uè¿™æ ïLš„æ•°æ®å­˜å‚¨æœåŠ¡ä¸­ï¼Œòq¶ä¸” Acegi 的管理器ž®†åœ¨˜qè¡Œæ—‰™€‰æ‹©åˆé€‚的提供者ã€?
处理½E‹åº
有时ä»ÕdŠ¡å¯èƒ½ä¼šè¢«åˆ†è§£ä¸ºå¤šä¸ªæ­¥éª¤ï¼Œå…¶ä¸­æ¯ä¸ªæ­¥éª¤ç”׃¸€ä¸ªç‰¹å®šçš„处理½E‹åºæ‰§è¡Œã€‚比方说åQŒAcegi çš?注销˜q‡æ×oå™?/em> 使用两个处理½E‹åºæ¥é€€å‡ÞZ¸€ä¸?HTTP 客户机。其中一个处理程序ä‹É用户çš?HTTP 会话无效åQŒè€Œå¦ä¸€ä¸ªå¤„理程序则删除用户çš?cookie。当æ ÒŽ®åº”用½E‹åºéœ€æ±‚配¾|?Acegi æ—Óž¼Œå¤šä¸ªå¤„理½E‹åºèƒ½å¤Ÿæä¾›å¾ˆå¥½çš„灵‹zÀL€§ã€‚您可以使用自己选择的处理程序来执行保护应用½E‹åºæ‰€éœ€çš„æ­¥éª¤ã€?

反è{控制

Acegi 的组仉™€šè¿‡å½¼æ­¤ä¹‹é—´çš„依赖来对企业应用程序进行保护。比如,一个èín份验证处理过滤器需要一个èín份验证管理器选择一个合适的íw«ä†¾éªŒè¯æä¾›è€…。这ž®±æ˜¯è¯´æ‚¨å¿…须能够表示和管ç?Acegi ¾l„äšg的依赖关¾p…R€?

IOC 实现通常用于½Ž¡ç† Java ¾l„äšg之间的依赖关¾p…R€‚IOC 提供了两个重要的ç‰ÒŽ€§ï¼š

  1. 它提供了一¿Uè¯­æ³•,表示应用½E‹åºæ‰€éœ€çš„组件以及这些组件如何相互依赖ã€?br />
  2. 它保证了所需的组件在˜qè¡Œæ—¶æ˜¯å¯ç”¨çš„ã€?

XML 配置文äšg

Acegi 使用 Spring 框架åQˆè¯·å‚见 参考资æ–?/a>åQ‰é™„带的‹¹è¡Œå¼€æº?IOC 实现来管理其¾l„äšg。Spring 需要您¾~–写一ä¸?XML 配置文äšg来表½Cºç»„件的依赖关系åQŒå¦‚清单 1 所½Cºï¼š


清单 1. Spring 配置文äšg的结æž?/strong>
                        <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 配置文äšg包含一ä¸?<beans> 标记åQŒå®ƒž®è£…了一些其他的 <bean> 标记。所有的 Acegi ¾l„äšgåQˆå³˜q‡æ×o器、管理器、提供者等åQ‰å®žé™…上都是 JavaBean。XML 配置文äšg中的每个 <bean> 标记都代表一ä¸?Acegi ¾l„äšgã€?/p>

˜q›ä¸€æ­¥è§£é‡?XML 配置文äšg

首先ž®†æ³¨æ„åˆ°çš„æ˜¯æ¯ä¸ª <bean> 标记都包含一ä¸?class 属性,˜q™ä¸ªå±žæ€§æ ‡è¯†ç»„件所使用的类ã€?code><bean> 标记˜q˜å…·æœ‰ä¸€ä¸?id 属性,它标识作ä¸?Acegi ¾l„äšg工作的实例(Java 对象åQ‰ã€?/p>

比方è¯ß_¼Œæ¸…单 1 的第一ä¸?<bean> 标记标识了名ä¸?filterChainProxy çš„ç»„ä»¶å®žä¾‹ï¼Œå®ƒæ˜¯åäØ“ org.acegisecurity.util.FilterChainProxy 的类的实例ã€?/p>

使用 <bean> 标记的子标记来表½C?bean 的依赖关¾p…R€‚比如,注意½W¬ä¸€ä¸?<bean> 标记çš?<property> 子标记ã€?code><property> 子标记定义了 <bean> 标记依赖的其ä»?bean 或倹{€?/p>

所以在 清单 1 中,½W¬ä¸€ä¸?<bean> 标记çš?<property> 子标记具有一ä¸?name 属性和一ä¸?<value> 子标讎ͼŒåˆ†åˆ«å®šä¹‰äº†è¿™ä¸?bean 依赖的属性的名称和倹{€?/p>

同样åQ?a cmimpressionsent="1">清单 1 中的½W¬äºŒä¸ªå’Œ½W¬ä¸‰ä¸?<bean> 标记定义了一个过滤器 bean 依赖于一个管理器 bean。第二个 <bean> 标记表示˜q‡æ×oå™?beanåQŒè€Œç¬¬ä¸‰ä¸ª <bean> 标记表示½Ž¡ç†å™?beanã€?/p>

˜q‡æ×o器的 <bean> 标记包含一ä¸?<property> 子标讎ͼŒè¯¥å­æ ‡è®°å…ähœ‰ä¸¤ä¸ªå±žæ€§ï¼šname å’?refã€?code>name 属性定义了˜q‡æ×oå™?bean 的属性,è€?ref 属性引用了½Ž¡ç†å™?bean 的实例(名称åQ‰ã€?/p>

下一节将展示如何åœ?XML 配置文äšg中配¾|?Acegi ˜q‡æ×o器。在本文后面的内容中åQŒæ‚¨ž®†åœ¨ä¸€ä¸ªæ ·ä¾?Acegi 应用½E‹åºä¸­ä‹É用过滤器ã€?/p>



回页�/strong>


安全˜q‡æ×oå™?/span>

æ­£å¦‚æˆ‘å‰é¢æåˆ°çš„ä¸€æ øP¼ŒAcegi 使用安全˜q‡æ×oå™¨äØ“ä¼ä¸šåº”ç”¨½E‹åºæä¾›íw«ä†¾éªŒè¯å’ŒæŽˆæƒæœåŠ¡ã€‚æ‚¨å¯ä»¥æ ÒŽ®åº”用½E‹åºçš„需要ä‹É用和配置不同¾cÕdž‹çš„过滤器。这一节将介绍五种最重要çš?Acegi 安全˜q‡æ×o器ã€?/p>

Session Integration Filter

Acegi çš?Session Integration FilteråQˆSIFåQ‰é€šå¸¸æ˜¯æ‚¨ž®†è¦é…ç½®çš„第一个过滤器。SIF 创徏了一ä¸?em>安全上下文对è±?/em>åQŒè¿™æ˜¯ä¸€ä¸ªä¸Žå®‰å…¨ç›¸å…³çš„信息的占位½W¦ã€‚å…¶ä»?Acegi ˜q‡æ×o器将安全信息保存在安全上下文中,也会使用安全上下文中可用的安全信息ã€?/p>

SIF åˆ›å¾å®‰å…¨ä¸Šä¸‹æ–‡åÆˆè°ƒç”¨˜q‡æ×o器链中的其他˜q‡æ×o器。然后其他过滤器‹‚€ç´¢å®‰å…¨ä¸Šä¸‹æ–‡òq¶å¯¹å…¶è¿›è¡Œæ›´æ”V€‚比如,Authentication Processing FilteråQˆæˆ‘ž®†ç¨åŽè¿›è¡Œä»‹¾lï¼‰ž®†ç”¨æˆ·ä¿¡æ¯ï¼ˆå¦‚用户名、密码和电子邮äšg地址åQ‰å­˜å‚¨åœ¨å®‰å…¨ä¸Šä¸‹æ–‡ä¸­ã€?

当所有的处理½E‹åºå®Œæˆå¤„理后,SIF ‹‚€æŸ¥å®‰å…¨ä¸Šä¸‹æ–‡æ˜¯å¦æ›´æ–°ã€‚如果ä“Q何一个过滤器对安全上下文做出了更改,SIF ž®†æŠŠæ›´æ”¹ä¿å­˜åˆ°æœåŠ¡å™¨ç«¯çš„ä¼šè¯å¯¹è±¡ä¸­ã€‚å¦‚æžœå®‰å…¨ä¸Šä¸‹æ–‡ä¸­æ²¡æœ‰å‘çŽîC“Q何更改,那么 SIF ž®†åˆ é™¤å®ƒã€?/p>

åœ?XML 配置文äšg中对 SIF ˜q›è¡Œäº†é…¾|®ï¼Œå¦‚清å?2 所½Cºï¼š


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

Authentication Processing Filter

Acegi 使用 Authentication Processing FilteråQˆAPFåQ‰è¿›è¡Œèín份验证。APF 使用一个èín份验证(或登录)表单åQŒç”¨æˆ·åœ¨å…¶ä¸­è¾“入用户名和密码åQŒåƈ触发íw«ä†¾éªŒè¯ã€?/p>

APF 执行所有的后端íw«ä†¾éªŒè¯å¤„理ä»ÕdŠ¡åQŒæ¯”å¦‚ä»Žå®¢æˆ·æœø™¯·æ±‚中提取用户名和密码åQŒä»ŽåŽç«¯ç”¨æˆ·åº“中è¯Õd–用户参数åQŒä»¥åŠä‹É用这些信息对用户˜q›è¡Œíw«ä†¾éªŒè¯ã€?

在配¾|?APF æ—Óž¼Œæ‚¨å¿…™åÀLä¾›å¦‚下参敎ͼš

  • Authentication manager 指定了用来管理èín份验证提供者的íw«ä†¾éªŒè¯½Ž¡ç†å™¨ã€?br />
  • Filter processes URL 指定了客户在ç™Õd½•½H—口中按ä¸?Sign In 按钮时要讉K—®çš?URL。收到这ä¸?URL 的请求后åQŒAcegi 立即调用 APFã€?br />
  • Default target URL 指定了成功进行èín份验证和授权后呈现给用户的页面ã€?br />
  • Authentication failure URL 指定了èín份验证失败情况下用户看到的页面ã€?

APF 从用æˆïLš„è¯äh±‚对象中得到用户名、密码和其他信息。它ž®†è¿™äº›ä¿¡æ¯ä¼ é€ç»™íw«ä†¾éªŒè¯½Ž¡ç†å™¨ã€‚èín份验证管理器使用适当的提供者从后端用户库中è¯Õd–详细的用户信息(如用户名、密码、电子邮件地址和用戯‚®¿é—®æƒåˆ©æˆ–ç‰ÒŽƒåQ‰ï¼Œå¯¹ç”¨æˆ¯‚¿›è¡Œèín份验证,òq¶å°†ä¿¡æ¯å­˜å‚¨åœ¨ä¸€ä¸?Authentication 对象中ã€?/p>

最后,APF ž®?Authentication 对象保存åœ?SIF 之前创徏的安全上下文中。存储在安全上下文中çš?Authentication 对象ž®†ç”¨äºŽåšå‡ºæŽˆæƒå†³½{–ã€?/p>

APF 的配¾|®å¦‚清单 3 所½Cºï¼š


清单 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>
            

可以从这ŒDµä»£ç ä¸­çœ‹åˆ°åQŒAPF 依赖于上面讨论的˜q™å››ä¸ªå‚数。每个参数都是作为清å?3 所½Cºçš„ <property> 标记配置的ã€?/p>

Logout Processing Filter

Acegi 使用一ä¸?Logout Processing FileråQˆLPFåQ‰ç®¡ç†æ³¨é”€å¤„理。当客户机发来注销è¯äh±‚æ—Óž¼Œž®†ä‹Éç”?LPF ˜q›è¡Œå¤„理。它标识了来自由客户机所调用 URL 的注销è¯äh±‚ã€?/p>

LPF 的配¾|®å¦‚清单 4 所½Cºï¼š


清单 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 在其构造方法中包含两个参数åQšæ³¨é”€æˆåŠŸ URLåQ?code>/logoutSuccess.jspåQ‰å’Œå¤„理½E‹åºåˆ—表。注销成功 URL 用来在注销˜q‡ç¨‹å®ŒæˆåŽé‡å®šå‘客户机。处理程序执行实际的注销˜q‡ç¨‹åQ›æˆ‘åœ¨è¿™é‡Œåªé…ç½®äº†ä¸€ä¸ªå¤„ç†ç¨‹åºï¼Œå› äØ“åªéœ€ä¸€ä¸ªå¤„ç†ç¨‹åºå°±å¯ä»¥ä½?HTTP ä¼šè¯å˜äØ“æ— æ•ˆã€‚æˆ‘ž®†åœ¨æœ¬ç³»åˆ—下一½‹‡æ–‡ç« ä¸­è®¨è®ºæ›´å¤šçš„处理程序ã€?/p>

Exception Translation Filter

Exception Translation FilteråQˆETFåQ‰å¤„理èín份验证和授权˜q‡ç¨‹ä¸­çš„异常情况åQŒæ¯”如授权失败。在˜q™äº›å¼‚常情况中,ETF ž®†å†³å®šå¦‚何进行操作ã€?/p>

比如åQŒå¦‚果一个没有进行èín份验证的用户试图讉K—®å—保护的资源åQŒETF ž®†æ˜¾½CÞZ¸€ä¸ªç™»å½•页面要求用戯‚¿›è¡Œèín份验证。类似地åQŒåœ¨æŽˆæƒå¤ÞpÓ|的情况下åQŒå¯ä»¥é…¾|?ETF 来呈çŽîC¸€ä¸?Access Denied ™åµé¢ã€?/p>

ETF 的配¾|®å¦‚清单 5 所½Cºï¼š


清单 5. 配置 ETF
                        <bean id="exceptionTranslationFilter"
            class="org.acegisecurity.ui.ExceptionTranslationFilter">
            <property name="authenticationEntryPoint">
            <bean
            class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
            <property name="loginFormUrl" value="/login.jsp" />
            </bean>
            </property>
            <property name="accessDeniedHandler">
            <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
            <property name="errorPage" value="/accessDenied.jsp" />
            </bean>
            </property>
            </bean>
            

正如清单 5 所½Cºï¼ŒETF 包含两个参数åQŒåä¸?authenticationEntryPoint å’?accessDeniedHandlerã€?code>authenticationEntryPoint 属性指定登录页面,è€?accessDeniedHandler 指定 Access Denied ™åµé¢ã€?/p>

拦截˜q‡æ×oå™?/span>

Acegi çš?em>拦截˜q‡æ×oå™?/em> 用于做出授权决策。您需要在 APF 成功执行íw«ä†¾éªŒè¯åŽå¯¹æ‹¦æˆª˜q‡æ×o器进行配¾|®ï¼Œä»¥ä‹É其发挥作用。拦截器使用应用½E‹åºçš„访问控制策略来做出授权军_®šã€?/p>

本系列的下一½‹‡æ–‡ç« å°†å±•示如何设计讉K—®æŽ§åˆ¶½{–ç•¥åQŒå¦‚何将它们托管在目录服务中åQŒä»¥åŠå¦‚何配¾|?Acegi 以读取您的访问控制策略。但是,目前我将¾l§ç®‹å‘您展示如何使用 Acegi 配置一个简单的讉K—®æŽ§åˆ¶½{–略。在本文后面的部分,您将看到使用½Ž€å•的讉K—®æŽ§åˆ¶½{–略构徏一个样例应用程序ã€?/p>

配置½Ž€å•的讉K—®æŽ§åˆ¶½{–略可分ä¸ÞZ¸¤ä¸ªæ­¥éª¤ï¼š

  1. ¾~–写讉K—®æŽ§åˆ¶½{–ç•¥ã€?br />
  2. æ ÒŽ®½{–略配置 Acegi 的拦截过滤器ã€?

步骤 1. ¾~–写½Ž€å•的讉K—®æŽ§åˆ¶½{–ç•¥

首先看一ä¸?清单 6åQŒå®ƒå±•示了如何定义一个用户及其用戯‚§’è‰ÔŒ¼š


清单 6. 为用户定义简单的讉K—®æŽ§åˆ¶½{–ç•¥
                        alice=123,ROLE_HEAD_OF_ENGINEERING
            

清单 6 所½Cºçš„讉K—®æŽ§åˆ¶½{–略定义了用户名 aliceåQŒå®ƒçš„密码是 123åQŒè§’色是 ROLE_HEAD_OF_ENGINEERING。(下一节将说明如何在文件中定义ä»ÀL„æ•°é‡çš„用户及其用戯‚§’è‰ÔŒ¼Œç„¶åŽé…ç½®æ‹¦æˆª˜q‡æ×o器以使用˜q™äº›æ–‡äšg。)

步骤 2. 配置 Acegi 的拦截过滤器

拦截˜q‡æ×o器ä‹É用三个组件来做出授权决策åQŒæˆ‘在清å?7 中对其进行了配置åQ?/p>
清单 7. 配置拦截˜q‡æ×oå™?
                        <bean id="filterInvocationInterceptor"
            class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="accessDecisionManager" ref="accessDecisionManager" />
            <property name="objectDefinitionSource">
            <value>
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /protected/**=ROLE_HEAD_OF_ENGINEERING
            /**=IS_AUTHENTICATED_ANONYMOUSLY
            </value>
            </property>
            <!--  More properties of the interceptor filter -->
            </bean>
            

如清å?7 所½Cºï¼Œé…ç½®æ‰€éœ€çš„三个组件是 authenticationManagerã€?code>accessDecisionManagerã€?code>objectDefinitionSourceåQ?/p>

  • authenticationManager ¾l„äšg与我在介¾l?Authentication Processing Filter æ—¶è®¨è®ø™¿‡çš„èín份验证管理器相同。拦截过滤器可以在授权的˜q‡ç¨‹ä¸­ä‹Éç”?authenticationManager 重新对客æˆähœº˜q›è¡Œíw«ä†¾éªŒè¯ã€?br />
  • accessDecisionManager ¾l„äšg½Ž¡ç†æŽˆæƒ˜q‡ç¨‹åQŒè¿™éƒ¨åˆ†å†…容ž®†åœ¨æœ¬ç³»åˆ—的下篇文章中详¾l†è®¨è®ºã€?br />
  • objectDefinitionSource ¾l„äšg包含对应于将要发生的授权的访问控制定义。例如,清单 7 中的 objectDefinitionSource 属性值包含两ä¸?URLåQ?code>/protected/* å’?/*åQ‰ã€‚其值定义了˜q™äº› URL 的角艌Ӏ?code>/protected/* URL 的角色是 ROLE_HEAD_OF_ENGINEERING。您可以æ ÒŽ®åº”用½E‹åºçš„需要定义ä“Q何角艌Ӏ?br />
    回想一ä¸?清单 6åQŒæ‚¨ä¸ºç”¨æˆ·å alice 定义äº?ROLE_HEAD_OF_ENGINEERING。这ž®±æ˜¯è¯?alice ž®†èƒ½å¤Ÿè®¿é—?/protected/* URLã€?




回页�/strong>


˜q‡æ×o器工作原ç?/span>

正如您已¾läº†è§£åˆ°çš„ä¸€æ øP¼ŒAcegi 的组件彼此依赖,从而对您的应用½E‹åº˜q›è¡Œä¿æŠ¤ã€‚在本文后面的部分,您将看到如何å¯?Acegi ˜q›è¡Œé…ç½®åQŒä»Žè€ŒæŒ‰ç…§ç‰¹å®šçš„™åºåºåº”用安全˜q‡æ×o器,因此需要创å»?em>˜q‡æ×o器链。出于这个目的,Acegi 保存了一个过滤器铑֯¹è±¡ï¼Œå®ƒå°è£…了ä¸ÞZ¿æŠ¤åº”用程序而配¾|®äº†çš„æ‰€æœ‰è¿‡æ»¤å™¨ã€‚图 1 展示äº?Acegi ˜q‡æ×o器链的生命周期,该周期从客户机向您的应用½E‹åºå‘é€?HTTP è¯äh±‚开始。(å›?1 昄¡¤ºäº†æœåŠ¡äºŽ‹¹è§ˆå™¨å®¢æˆähœºçš„容器。)


å›?1. 托管 Acegi ˜q‡æ×o器链以安全地为浏览器客户机服务的容器
Acegi ˜q‡æ×o器的生命周期

下面的步骤描˜qîCº†˜q‡æ×o器链的生命周期:

  1. ‹¹è§ˆå™¨å®¢æˆähœºå‘您的应用程序发é€?HTTP è¯äh±‚ã€?br />
  2. 容器接收åˆ?HTTP è¯äh±‚òq¶åˆ›å»ÞZ¸€ä¸ªè¯·æ±‚对象,该对象将ž®è£… HTTP è¯äh±‚中包含的信息。容器还创徏一个各¿Uè¿‡æ»¤å™¨éƒ½å¯å¤„ç†çš„å“åº”å¯¹è±¡ï¼Œä»Žè€ŒäØ“å‘å‡ºè¯äh±‚的客æˆähœºå‡†å¤‡å¥?HTTP 响应。容器然后调ç”?Acegi 的过滤器链代理,˜q™æ˜¯ä¸€ä¸ªä»£ç†è¿‡æ»¤å™¨ã€‚该代理知道应用的过滤器的实际顺序。当容器调用代理æ—Óž¼Œå®ƒå°†å‘代理发送请求、响应以及过滤器铑֯¹è±¡ã€?br />
  3. 代理˜q‡æ×o器调用过滤器链中½W¬ä¸€ä¸ªè¿‡æ»¤å™¨åQŒå‘其发送请求、响应和˜q‡æ×o器链对象ã€?br />
  4. 链中的过滤器逐个执行其处理。一个过滤器可以通过调用˜q‡æ×o器链中下一个过滤器随时¾lˆæ­¢è‡ªèín处理。有的过滤器甚至æ ÒŽœ¬ä¸æ‰§è¡Œä“Q何处理(比如åQŒå¦‚æž?APF 发现一个到来的è¯äh±‚没有要求íw«ä†¾éªŒè¯åQŒå®ƒå¯èƒ½ä¼šç«‹å³ç»ˆæ­¢å…¶å¤„理åQ‰ã€?

  5. 当èín份验证过滤器完成其处理时åQŒè¿™äº›è¿‡æ»¤å™¨ž®†æŠŠè¯äh±‚和响应对象发送到应用½E‹åºä¸­é…¾|®çš„æ‹¦æˆª˜q‡æ×o器ã€?br />
  6. 拦截器决定是否对发出è¯äh±‚的客æˆähœº˜q›è¡ŒæŽˆæƒåQŒä‹É它访问所è¯äh±‚的资源ã€?br />
  7. 拦截器将控制权传输给应用½E‹åºåQˆæ¯”如,成功˜q›è¡Œäº†èín份验证和授权的客æˆähœºè¯äh±‚çš?JSP ™åµé¢åQ‰ã€?br />
  8. 应用½E‹åºæ”¹å†™å“åº”对象的内宏V€?br />
  9. 响应对象已经准备好了åQŒå®¹å™¨å°†å“åº”对象转换ä¸?HTTP 响应åQŒåƈž®†å“åº”发送到发出è¯äh±‚的客æˆähœºã€?br />

为帮助您˜q›ä¸€æ­¥ç†è§?Acegi ˜q‡æ×o器,我将详细探讨其中两个˜q‡æ×o器的操作åQšSession Integration Filter å’?Authentication Processing Filterã€?/p>

SIF 如何创徏一个安全上下文

å›?2 展示äº?SIF 创徏安全上下文所涉及到的步骤åQ?/p>
�2. SIF 创徏安全上下�/strong>
SIF 如何创徏安全上下� src=

现在详细地考虑下面˜q™äº›æ­¥éª¤åQ?/p>

  1. Acegi 的过滤器链代理调ç”?SIF òq¶å‘其发送请求、响应和˜q‡æ×o器链对象。注意:通常ž®?SIF é…ç½®ä¸ø™¿‡æ»¤å™¨é“¾ä¸­½W¬ä¸€ä¸ªè¿‡æ»¤å™¨ã€?br />
  2. SIF ‹‚€æŸ¥å®ƒæ˜¯å¦å·²ç»å¯¹è¿™ä¸?Web è¯äh±‚˜q›è¡Œ˜q‡å¤„理。如果是的话åQŒå®ƒž®†ä¸å†è¿›ä¸€æ­¥è¿›è¡Œå¤„理,òq¶å°†æŽ§åˆ¶æƒä¼ è¾“ç»™˜q‡æ×o器链中的下一个过滤器åQˆå‚见下面的½W?4 个步骤)。如æž?SIF 发现˜q™æ˜¯½W¬ä¸€‹Æ¡å¯¹˜q™ä¸ª Web è¯äh±‚调用 SIFåQŒå®ƒž®†è®¾¾|®ä¸€ä¸ªæ ‡è®ŽÍ¼Œž®†åœ¨ä¸‹ä¸€‹Æ¡ä‹É用该标记åQŒä»¥è¡¨ç¤ºæ›„¡»è°ƒç”¨˜q?SIFã€?br />
  3. SIF ž®†æ£€æŸ¥æ˜¯å¦å­˜åœ¨ä¸€ä¸ªä¼šè¯å¯¹è±¡ï¼Œä»¥åŠå®ƒæ˜¯å¦åŒ…含安全上下文。它从会话对象中‹‚€ç´¢å®‰å…¨ä¸Šä¸‹æ–‡åQŒåƈž®†å…¶æ”„¡½®åœ¨åä¸?security context holder çš„äÍ时占位符中。如果不存在会话对象åQŒSIF ž®†åˆ›å»ÞZ¸€ä¸ªæ–°çš„安全上下文åQŒåƈž®†å®ƒæ”‘Öˆ° security context holder 中。注意:security context holder 位于应用½E‹åºçš„范围内åQŒæ‰€ä»¥å¯ä»¥è¢«å…¶ä»–的安全过滤器讉K—®ã€?br />
  4. SIF 调用˜q‡æ×o器链中的下一个过滤器ã€?br />
  5. å…¶ä»–˜q‡æ×o器可以编辑安全上下文ã€?br />
  6. SIF 在过滤器铑֮Œæˆå¤„理后接收控制权ã€?br />
  7. SIF ‹‚€æŸ¥å…¶ä»–çš„˜q‡æ×o器是否在其处理过½E‹ä¸­æ›´æ”¹äº†å®‰å…¨ä¸Šä¸‹æ–‡åQˆæ¯”如,APF 可能ž®†ç”¨æˆ¯‚¯¦¾l†ä¿¡æ¯å­˜å‚¨åœ¨å®‰å…¨ä¸Šä¸‹æ–‡ä¸­åQ‰ã€‚如果是的话åQŒå®ƒž®†æ›´æ–îC¼šè¯å¯¹è±¡ä¸­çš„安全上下文。就是说在过滤器铑֤„理过½E‹ä¸­åQŒå¯¹å®‰å…¨ä¸Šä¸‹æ–‡çš„ä»ÖM½•更改现在都保存在会话对象中ã€?

APF 如何对用戯‚¿›è¡Œèín份验è¯?/span>

å›?3 展示äº?APF 对用戯‚¿›è¡Œèín份验证所涉及到的步骤åQ?/p>
å›?3. APF 对用戯‚¿›è¡Œèín份验è¯?/strong>
APF 如何对用戯‚¿›è¡Œèín份验è¯? src=

现在仔细考虑以下˜q™äº›æ­¥éª¤åQ?/p>

  1. ˜q‡æ×o器链中前面的˜q‡æ×o器向 APF 发送请求、响应和˜q‡æ×oé“‘Ö¯¹è±¡ã€?br />
  2. APF ä½¿ç”¨ä»Žè¯·æ±‚å¯¹è±¡ä¸­èŽ·å¾—çš„ç”¨æˆ·åã€å¯†ç ä»¥åŠå…¶ä»–ä¿¡æ¯åˆ›å»ø™ín份验证标记ã€?br />
  3. APF ž®†èín份验证标è®îC¼ é€’ç»™íw«ä†¾éªŒè¯½Ž¡ç†å™¨ã€?br />
  4. íw«ä†¾éªŒè¯½Ž¡ç†å™¨å¯èƒ½åŒ…含一个或更多íw«ä†¾éªŒè¯æä¾›è€…。每个提供者恰好支持一¿Uç±»åž‹çš„íw«ä†¾éªŒè¯ã€‚管理器‹‚€æŸ¥å“ªä¸€¿Uæä¾›è€…支持它ä»?APF 收到的èín份验证标记ã€?br />
  5. íw«ä†¾éªŒè¯½Ž¡ç†å™¨å°†íw«ä†¾éªŒè¯æ ‡è®°å‘送到适合˜q›è¡Œíw«ä†¾éªŒè¯çš„æä¾›è€…ã€?br />
  6. íw«ä†¾éªŒè¯æä¾›è€…支持从íw«ä†¾éªŒè¯æ ‡è®°ä¸­æå–用户名åQŒåƈž®†å®ƒå‘é€ç»™åäØ“ user cache service 的服务。Acegi ¾~“存了已¾lè¿›è¡Œè¿‡íw«ä†¾éªŒè¯çš„用戗÷€‚该用户下次ç™Õd½•æ—Óž¼ŒAcegi 可以从缓存中加蝲他或她的详细信息åQˆæ¯”如用户名、密码和权限åQ‰ï¼Œè€Œä¸æ˜¯ä»ŽåŽç«¯æ•°æ®å­˜å‚¨ä¸­è¯»å–数据。这¿Uæ–¹æ³•ä‹É得性能得到了改善ã€?br />
  7. user cache service ‹‚€æŸ¥ç”¨æˆïLš„详细信息是否存在于缓存中ã€?br />
  8. user cache service ž®†ç”¨æˆïLš„详细信息˜q”回¾l™èín份验证提供者。如果缓存不包含用户详细信息åQŒåˆ™˜q”回 nullã€?br />
  9. íw«ä†¾éªŒè¯æä¾›è€…检查缓存服务返回的是用æˆïLš„详细信息˜q˜æ˜¯ nullã€?br />
  10. 如果¾~“å­˜˜q”回 nullåQŒèín份验证提供者将用户名(在步éª?6 中提取)发送给另一个名ä¸?user details service 的服务ã€?

  11. user details service 与包含用戯‚¯¦¾l†ä¿¡æ¯çš„后端数据存储通信åQˆå¦‚目录服务åQ‰ã€?

  12. user details service ˜q”回用户的详¾l†ä¿¡æ¯ï¼Œæˆ–者,如果找不到用戯‚¯¦¾l†ä¿¡æ¯åˆ™æŠ›å‡ºíw«ä†¾éªŒè¯å¼‚常ã€?br />
  13. 如果 user cache service 或è€?user details service ˜q”回有效的用戯‚¯¦¾l†ä¿¡æ¯ï¼Œíw«ä†¾éªŒè¯æä¾›è€…将使用 user cache service æˆ?user details service ˜q”回的密码来匚w…ç”¨æˆ·æä¾›çš„安全标讎ͼˆå¦‚密码)。如果找åˆîC¸€ä¸ªåŒ¹é…ï¼Œíw«ä†¾éªŒè¯æä¾›è€…将用户的详¾l†ä¿¡æ¯è¿”回给íw«ä†¾éªŒè¯½Ž¡ç†å™¨ã€‚否则的话,则抛å‡ÞZ¸€ä¸ªèín份验证异常ã€?br />
  14. íw«ä†¾éªŒè¯½Ž¡ç†å™¨å°†ç”¨æˆ·çš„详¾l†ä¿¡æ¯è¿”回给 APF。这æ ïL”¨æˆ·å°±æˆåŠŸåœ°è¿›è¡Œäº†íw«ä†¾éªŒè¯ã€?br />
  15. APF ž®†ç”¨æˆ¯‚¯¦¾l†ä¿¡æ¯ä¿å­˜åœ¨ å›?2 所½Cºç”±æ­¥éª¤ 3 创徏的安全上下文中ã€?br />
  16. APF ž®†æŽ§åˆ¶æƒä¼ è¾“¾l™è¿‡æ»¤å™¨é“¾ä¸­çš„下一个过滤器ã€?




回页�/strong>


一个简单的 Acegi 应用½E‹åº

在本文中åQŒæ‚¨å·²ç»äº†è§£äº†å¾ˆå¤šå…³äº?Acegi 的知识,所以现在看一下利用您目前学到的知识能做些什么,从而结束本文。对于这个简单的演示åQŒæˆ‘设计了一个样例应用程序(参见 下蝲åQ‰ï¼Œòq¶å¯¹ Acegi ˜q›è¡Œäº†é…¾|®ä»¥ä¿æŠ¤å®ƒçš„一些资源ã€?

样例应用½E‹åºåŒ…含 5 ä¸?JSP ™åµé¢åQšindex.jsp、protected1.jsp、protected2.jsp、login.jsp å’?accessDenied.jspã€?/p>

index.jsp 是应用程序的‹Æ¢è¿Ž™åµé¢ã€‚它向用æˆäh˜¾½CÞZº†ä¸‰ä¸ª­‘…链接,如图 4 所½Cºï¼š


å›?4. 样例应用½E‹åºçš„æ¬¢˜qŽé¡µé¢ï¼š
一个简单的 Acegi 应用½E‹åº

å›?4 所½Cºçš„链接中,其中两个链接指向了被保护的资源(protected1.jsp å’?protected2.jspåQ‰ï¼Œ½W¬ä¸‰ä¸ªé“¾æŽ¥æŒ‡å‘登录页面(login.jspåQ‰ã€‚只有在 Acegi 发现用户没有被授权访问受保护的资源时åQŒæ‰ä¼šæ˜¾½C?accessDenied.jsp ™åµé¢ã€?/p>

如果用户试图讉K—®ä»ÖM½•受保护的™åµé¢åQŒæ ·ä¾‹åº”用程序将昄¡¤ºç™Õd½•™åµé¢ã€‚当用户使用ç™Õd½•™åµé¢˜q›å…¥åŽï¼Œåº”用½E‹åºž®†è‡ªåŠ¨é‡å®šå‘åˆ°è¢«è¯äh±‚的受保护资源ã€?/p>

用户可以通过单击‹Æ¢è¿Ž™åµé¢ä¸­çš„½W¬ä¸‰ä¸ªé“¾æŽ¥ç›´æŽ¥è¯·æ±‚登录页面。这¿Uæƒ…况下åQŒåº”用程序显½Cºç”¨æˆ·å¯ä»¥è¿›å…¥ç³»¾lŸçš„ç™Õd½•™åµé¢ã€‚进入系¾lŸä»¥åŽï¼Œåº”用½E‹åºž®†ç”¨æˆ·é‡å®šå‘åˆ?protected1.jspåQŒå®ƒæ˜¯ç”¨æˆ¯‚¿›å…¥ç³»¾lŸè€Œæ²¡æœ‰è¯·æ±‚特定的受保护资源时昄¡¤ºçš„默认资源ã€?/p>

配置样例应用½E‹åº

为本文下载的源代码包含一个名ä¸?acegi-config.xml çš?XML 配置文äšgåQŒå®ƒåŒ…含 Acegi ˜q‡æ×o器的配置。根æ?安全˜q‡æ×o器的讨论 中的½CÞZ¾‹åQŒæ‚¨åº”该很熟悉这些配¾|®ã€?/p>

我还为样例应用程序编写了一ä¸?web.xml æ–‡äšgåQŒå¦‚清单 8 所½Cºï¼š


清单 8. 样例应用½E‹åºçš?web.xml æ–‡äšg
                        <web-app>
            <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/acegi-config.xml</param-value>
            </context-param>
            <filter>
            <filter-name>Acegi Filter Chain Proxy</filter-name>
            <filter-class>
            org.acegisecurity.util.FilterToBeanProxy
            </filter-class>
            <init-param>
            <param-name>targetClass</param-name>
            <param-value>
            org.acegisecurity.util.FilterChainProxy
            </param-value>
            </init-param>
            </filter>
            <filter-mapping>
            <filter-name>Acegi Filter Chain Proxy</filter-name>
            <url-pattern>/*</url-pattern>
            </filter-mapping>
            <listener>
            <listener-class>
            org.springframework.web.context.ContextLoaderListener
            </listener-class>
            </listener>
            </web-app>
            

web.xml æ–‡äšg配置如下åQ?/p>

  • acegi-config.xml æ–‡äšgçš?URL 位于 <context-param> 标记中ã€?br />
  • Acegi ˜q‡æ×o器链代理¾cȝš„名称位于 <filter> 标记中ã€?br />
  • URL åˆ?Acegi ˜q‡æ×o器链代理的映ž®„在 <filter-mapping> 标记中。注意:您可以简单地ž®†åº”用程序的所æœ?URLåQ?code>/*åQ‰æ˜ ž®„到 Acegi ˜q‡æ×o器链代理。Acegi ž®†å¯¹æ˜ å°„åˆ?Acegi ˜q‡æ×o器链代理上的所æœ?URL 应用安全性ã€?br />
  • 应用½E‹åºä¸Šä¸‹æ–‡åŠ è½½ç¨‹åºä½äº?<listener> 标记中,它将加蝲 Spring çš?IOC 框架ã€?

部çÖvòq¶è¿è¡Œåº”用程åº?/span>

部çÖvòq¶è¿è¡Œæ ·ä¾‹åº”用程序非常的½Ž€å•。只需要完成两件事情:

  1. ž®?acegisample.war æ–‡äšg从本教程下蝲的源代码中复制到安装 Tomcat çš?webapps 目录中ã€?br />
  2. ä»?Acegi Security System 主页 下蝲òq¶è§£åŽ‹ç¾ƒ acegi-security-1.0.3.zip。您ž®†æ‰¾åˆîC¸€ä¸ªåä¸?acegi-security-sample-tutorial.war 的样例应用程序。解压羃 war æ–‡äšgòq¶æå–å…¶ WEB-INF/lib æ–‡äšg夹中所有的 jar æ–‡äšg。将所有的 JAR æ–‡äšgä»?WEB-INF/lib æ–‡äšg夹中复制åˆ?theacegisample.war 应用½E‹åºçš?WEB-INF/lib æ–‡äšg夏V€?

现在åQŒæ‚¨å·²ç»ä¸ø™¿è¡Œæ ·ä¾‹åº”用程序做好准备了。启åŠ?Tomcat òq¶å°†‹¹è§ˆå™¨æŒ‡å?http://localhost:8080/acegisample/ã€?/p>

您将看到 å›?4 所½Cºçš„‹Æ¢è¿Ž™åµé¢åQŒä½†æ˜¯æ­¤æ—¶æ˜¾½Cºçš„™åµé¢æ˜¯çœŸå®žçš„。请¾l§ç®‹˜qè¡Œ½E‹åºåQŒåƈ查看在尝试访问欢˜qŽé¡µé¢æ˜¾½Cºçš„不同链接时会发生什么状å†üc€?/p>



回页�/strong>


¾l“束è¯?/span>

åœ?em>使用 Acegi 保护 Java 应用½E‹åº ¾pÕdˆ—的第一½‹‡æ–‡ç« ä¸­åQŒæ‚¨äº†è§£äº?Acegi 安全¾pȝ»Ÿçš„特性、架构和¾l„äšgåQŒå­¦ä¹ äº†å¤§é‡æœ‰å…³ Acegi 安全˜q‡æ×o器的知识åQŒè¿™äº›è¿‡æ»¤å™¨è¢«é›†æˆåˆ° Acegi 的安全框架中。您˜q˜å­¦ä¹ äº†å¦‚何使用 XML 配置文äšg配置¾l„äšg依赖关系åQŒåƈ查看äº?Acegi 的安全过滤器在样例程序中工作的情形,该应用程序可以实现基äº?URL 的安全性ã€?

本文所˜q°çš„安全技术非常的½Ž€å•,所ä»?Acegi 使用˜q™äº›æŠ€æœ¯å®žçŽ°å®‰å…¨æ€§ã€‚æœ¬¾pÕdˆ—的下一文章ž®†å¼€å§‹ä»‹¾l?Acegi 的一些较为高¾U§çš„应用åQŒé¦–先是¾~–写讉K—®æŽ§åˆ¶åè®®òq¶å°†å…¶å­˜å‚¨åˆ°ç›®å½•服务中。您˜q˜å°†äº†è§£åˆ°å¦‚何配¾|?AcegiåQŒä‹É它与目录服务交互åQŒä»Žè€Œå®žçŽ°æ‚¨çš„è®¿é—®æŽ§åˆ¶ç­–ç•¥ã€?/p>




回页�/strong>


下蝲

描述 名字 大小 下蝲æ–ÒŽ³•
本文源代�/th> j-acegi1.zip 10KB HTTP
关于下蝲æ–ÒŽ³•的信æ?/a>


参考资�

学习

获得产品和技�/strong>

讨论


关于作�/span>

 

Bilal Siddiqui 是一名电子工½E‹å¸ˆã€XML ™åùN—®åQŒä»–˜q˜æ˜¯ WaxSysåQˆä¸»è¦ä»Žäº‹ç”µå­å•†åŠ¡ç®€åŒ–ï¼‰çš„åˆ›å»ø™€…之一。自ä»?1995 òq´æ¯•业于拉合ž®”å·¥½E‹æŠ€æœ¯å¤§å­¦ï¼ˆUniversity of Engineering and TechnologyåQŒLahoreåQ‰ç”µå­å·¥½E‹ä¸“ä¸šä»¥åŽï¼Œä»–å°±å¼€å§‹äØ“å·¥ä¸šæŽ§åˆ¶¾pȝ»Ÿè®¾è®¡å„种软äšg解决æ–ÒŽ¡ˆã€‚稍后,他致力于 XML æ–šw¢òq¶ä‹É用他åœ?C++ ¾~–程中取得的¾léªŒæ¥æž„建基äº?Web å’?WAP çš?XML 处理工具、服务器端解析方案和服务应用½E‹åºã€‚Bilal 是一名技术推òq¿è€…,òq¶ä¸”是一名多产的技术作家ã€?/p>



来自:http://www.cnblogs.com/amboyna/archive/2008/03/25/1122079.html

]]>实战AcegiåQšä‹É用Acegiä½œäØ“åŸÞZºŽSpring框架的WEB应用的安全框æž?/title><link>http://www.aygfsteel.com/waterjava/archive/2008/05/08/199308.html</link><dc:creator>狼爱上狸</dc:creator><author>狼爱上狸</author><pubDate>Thu, 08 May 2008 10:37:00 GMT</pubDate><guid>http://www.aygfsteel.com/waterjava/archive/2008/05/08/199308.html</guid><wfw:comment>http://www.aygfsteel.com/waterjava/comments/199308.html</wfw:comment><comments>http://www.aygfsteel.com/waterjava/archive/2008/05/08/199308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/waterjava/comments/commentRss/199308.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/waterjava/services/trackbacks/199308.html</trackback:ping><description><![CDATA[<p>最˜q‘项目ä‹É用Acegiä½œäØ“å®‰å…¨æ¡†æž¶çš„å®žçŽ?效果不错,ž®±å†™äº†è¿™½‹‡æ–‡ç« ä½œä¸ºæ€È»“.<br /> <br /> 对于ä»ÖM½•一个完整的应用¾pȝ»ŸåQŒå®Œå–„的认证和授权机制是必不可少的。在åŸÞZºŽSpringFrameworkçš„WEB应用中,<br /> 我们可以使用Acegiä½œäØ“å®‰å…¨æž¶æž„çš„å®žçŽ°ã€‚æœ¬æ–‡å°†ä»‹ç»å¦‚ä½•åœ¨åŸºäºŽSpring构架的Web应用中ä‹É用AcegiåQŒåƈ且详¾l†ä»‹<br /> ¾lå¦‚何配¾|®å’Œæ‰©å±•Acegi框架以适应实际需要ã€?br /> </p> <p>文章和代码下è½?<br /> <br /> <a href="http://www.aygfsteel.com/Files/youlq/Acegi.zip">http://www.aygfsteel.com/Files/youlq/Acegi.zip</a><br /> <br /> <br /> <strong><font color="#ff0000">注意åQšè®¸å¤šæœ‹å‹åœ¨éƒ¨çÖv上遇åˆîC¸€äº›éº»çƒ¦ï¼Œæ‰€ä»¥æˆ‘ž®†å¯ä»¥éƒ¨¾|²çš„完整的waræ–‡äšg传上来,注意åQšjava代码在acegi-sample.war\WEB-INF 目录下,例子需要MysqlåQŒå¾åº“脚本在acegi-sample.war\db目录下ã€?/font></strong><br /> <br /> <a href="http://www.aygfsteel.com/Files/youlq/acegi-sample.part1.rar"><font color="#002c99">acegi-sample.part1.rar</font></a><br /> <a href="http://www.aygfsteel.com/Files/youlq/acegi-sample.part2.rar"><font color="#002c99">acegi-sample.part2.rar</font></a><br /> <a href="http://www.aygfsteel.com/Files/youlq/acegi-sample.part3.rar"><font color="#002c99">acegi-sample.part3.rar</font></a><br /> <a href="http://www.aygfsteel.com/Files/youlq/acegi-sample.part4.rar"><font color="#002c99">acegi-sample.part4.rar</font></a><br /> <br /> 附注åQ?br /> <br /> 有些朋友询问我如何部¾|²æ–‡ä¸­çš„例子åQŒåœ¨æ­¤å†‹Æ¡è¯´æ˜Žä¸€ä¸‹ï¼ˆæ–‡ç« ä¸­å·²¾læœ‰æåˆ°åQ‰ï¼š<br /> <br /> Mysql的徏表脚本在db目录ä¸?br /> ä¸ÞZº†å‡å°ä½“积åQŒå·²¾lå°†WEB-INF\lib下的依赖包删除,误‚‡ªè¡Œä¸‹è½½ä»¥ä¸‹åŒ…åQŒåƈ拯‚´è‡³WEB-INF\lib下:<br /> spring-1.2.4.jar<br /> acegi-security-0.8.3.jar<br /> aopalliance-1.0.jar<br /> c3p0-0.9.0.jar<br /> commons-logging-1.0.4.jar<br /> ehcache-1.1.jar<br /> log4j-1.2.8.jar<br /> mysql-connector-java-3.1.10-bin.jar<br /> oro-2.0.8.jar<br /> <br /> 提示åQ?br /> acegi-security-0.8.3.jar<br /> aopalliance-1.0.jar<br /> c3p0-0.9.0.jar<br /> commons-logging-1.0.4.jar<br /> ehcache-1.1.jar<br /> log4j-1.2.8.jar<br /> oro-2.0.8.jar<br /> 可以在acegi-security-0.8.3.zip所带的acegi-security-sample-contacts-filter.war中找到ã€?br /> spring-1.2.4.jar<br /> mysql-connector-java-3.1.10-bin.jar<br /> 要分别到springframeworkå’Œmysql¾|‘站下蝲ã€?/p> <br /> 来自:http://www.aygfsteel.com/youlq/archive/2005/12/06/22678.html <img src ="http://www.aygfsteel.com/waterjava/aggbug/199308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/waterjava/" target="_blank">狼爱上狸</a> 2008-05-08 18:37 <a href="http://www.aygfsteel.com/waterjava/archive/2008/05/08/199308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Acegi的下载和安装http://www.aygfsteel.com/waterjava/archive/2008/05/08/199307.html狼爱上狸狼爱上狸Thu, 08 May 2008 10:35:00 GMThttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199307.htmlhttp://www.aygfsteel.com/waterjava/comments/199307.htmlhttp://www.aygfsteel.com/waterjava/archive/2008/05/08/199307.html#Feedback0http://www.aygfsteel.com/waterjava/comments/commentRss/199307.htmlhttp://www.aygfsteel.com/waterjava/services/trackbacks/199307.html1  Acegi官方发布版的下蝲和安è£?/h3>

开发者可以通过http://sourceforge.net/projects/acegisecurity或http://acegisecurity.org/下蝲到Acegi官方发布版,比如acegi-security-1.x.zip。图4-4展示了SF中Acegi™å¹ç›®çš„首™åµï¼Œå®ƒæä¾›äº†ä¸‹è²AcegiåQˆSpring SecurityåQ‰çš„入口ã€?/p>

å›?-4  http://sourceforge.net/projects/acegisecurity首页

在单å‡Õd›¾4-4中的下蝲åQ?#8220;Download Acegi Security System for Spring”åQ‰è¶…链接后,开发者进而能够下载到最新的Acegi官方发布包。此æ—Óž¼Œå»ø™®®å¼€å‘者同时将acegi-security-1.x.zip、acegi-security-1.x-src.zip下蝲到本圎ͼŒå‰è€…包含了Jar存档和若òq²Acegi使能应用åQŒè€ŒåŽè€…仅仅包含了Acegi™å¹ç›®çš„æºä»£ç ã€?/p>

在下载到Acegi官方发布版后åQŒé€šè¿‡è§£åŽ‹acegi-security-1.x.zipåQŒå¼€å‘者能够浏览到如图4-5所½Cºçš„¾cÖM¼¼å†…容ã€?/p>

å›?-5  acegi-security-1.x.zip包含的内å®?/p>

通常åQŒå¤§éƒ¨åˆ†Acegi安全性项目仅仅需要ä‹É用到acegi-security-1.x.jar存档åQŒè¿™æ˜¯Acegi的核心包åQŒä“Q何Acegi使能™å¹ç›®éƒ½éœ€è¦ä‹É用到它。如果项目打½Ž—采用Java SE 5引入的Annotation注释支持åQŒåˆ™˜q˜éœ€è¦å°†acegi-security-tiger-1.x.jaræ·ÕdŠ åˆ°WEB-INF/lib中。如果开发者在使用Acegi提供的容器适配器支持,则还需要将acegi-security-catalina-1.x.jaråQˆé’ˆå¯¹TomcatåQ‰ã€acegi-security-jboss-1.x.jaråQˆé’ˆå¯¹JBossåQ‰ã€acegi-security-jetty-1.x.jaråQˆé’ˆå¯¹JettyåQ‰ã€acegi-security-resin-1.x.jaråQˆé’ˆå¯¹ResinåQ‰ç­‰Jar存档复制到相应的位置åQŒè‡³äºŽè¿™äº›Jar包的具体使用åQŒæœ¬ä¹¦å°†åœ¨ç¬¬10章详¾l†é˜˜q°ã€?/p>

另外åQŒacegi-security-sample-contacts-filter.war、acegi-security-sample-tutorial.war是两个直接可部çÖv到Java EE容器åQˆTomcat容器åQ‰ä¸­çš„Web应用ã€?/p>

2  Subversion中的Acegi源码下蝲和安è£?/h3>

如今åQŒAcegiåŸÞZ»£ç é‡‡ç”¨Subversion½Ž¡ç†ã€‚开发者通过如图4-6所½Cºçš„Web™åµé¢èƒ½å¤ŸèŽ·å¾—Subversion下蝲地址åQˆhttp://sourceforge.net/svn/?group_id=104215åQ‰ã€?/p>

å›?-6  èŽ·å¾—ä¸‹è²AcegiåŸÞZ»£ç åœ°å€çš„Web™åµé¢

事实上,AcegiåQˆSpring SecurityåQ‰åŸºä»£ç æœ¬èínž®±æ˜¯ä¸€ä¸ªEclipse Java™å¹ç›®åQŒè€Œä¸”它的构徏、管理工作采用了Maven 1.x/2.xåQˆhttp://maven.apache.org/åQ‰ã€‚开发者可以借助Eclipse Subversive插äšg从Subversion存储源获得Acegi的最新基代码。图4-7展示了Subversive内置的SVN Repository Exploringã€?/p>

å›?-7  Subversive插äšg使用截图

一旦在下蝲完成AcegiåQˆSpring SecurityåQ‰åŸºä»£ç åŽï¼Œå¼€å‘者将能够持箋监控到Acegi™å¹ç›®çš„æœ€æ–°æƒ…况,比如获得Acegi持箋更新的基代码、Acegi官方文档åQŒå›¾4-8展示了相应的使用截图ã€?/p>

å›?-8  æŒç®‹æ›´æ–°AcegiåŸÞZ»£ç ?/p>

3  有关Acegi的权威去å¤?/h3>

其一åQŒå¼€å‘者可以去订阅acegisecurity-developer@lists.sourceforge.neté‚®äšg列表åQŒå›¾4-9展示了订阅这一邮äšg列表的入口。Acegi开发团队积极参与到˜q™ä¸€é‚®äšg列表中,因此开发者从˜q™ä¸€é‚®äšg列表能够获得Acegi的最新进展ã€?/p>

å›?-9  è®¢é˜…Acegi开发者邮件列è¡?/p>

其二åQŒAcegi官方论坛åQˆhttp://forum.springframework.org/åQ‰ï¼Œå›?-10展示了论坛截图ã€?/p>

å›?-10  Acegi官方论坛

开发者可以通过许多渠道获得一手的Acegi知识、开发和部çÖv¾léªŒã€?/p>

5  ž®ç»“

本章围绕AcegiåQˆSpring SecurityåQ‰çš„认证½{–ç•¥˜q›è¡Œäº†é˜˜qŽÍ¼Œæ¯”如åŸÞZºŽ˜q‡æ×o器的设计、与认证源解耦、AcegiSecurityException异常体系½{‰ã€‚另外,我们˜q˜é’ˆå¯¹Acegi发布版和åŸÞZ»£ç çš„下蝲˜q›è¡Œäº†ç®€è¦ä»‹¾lã€?/p>

下章ž®†æ·±å…¥åˆ°Acegi支持的各¿Uè®¤è¯æœºåˆ¶ä¸­ã€?/p>

【参考及推荐资料�/h4>

l  http://acegisecurity.org/

l  http://sourceforge.net/projects/acegisecurity

http://www.polarion.org/index.php?page=overview&project=subversive


来自:http://book.csdn.net/bookfiles/310/10031012826.shtml


]]> Ö÷Õ¾Ö©Öë³ØÄ£°å£º ½­Ô´ÏØ| ÊÙÑôÏØ| ÆÖ³ÇÏØ| ¸»ÃñÏØ| ³²ºþÊÐ| ÐÅÒËÊÐ| ÉñÄ¾ÏØ| ¯»ôÏØ| ¼ÃÔ´ÊÐ| ¼¦Î÷ÊÐ| ³²ºþÊÐ| ÉÜÐËÊÐ| ˳ÒåÇø| °²Ë³ÊÐ| ¹þ¶û±õÊÐ| ¼¦ÔóÏØ| ɽÎ÷Ê¡| ÁÙÔóÏØ| вÌÏØ| ÁéÊ¯ÏØ| Ù¤Ê¦ÏØ| ƽºþÊÐ| Ò˳ÇÊÐ| ƽÀûÏØ| Íå×ÐÇø| ÄÏÑôÊÐ| ÏæÏçÊÐ| Îñ´¨| ÇåºÓÏØ| Ëç±õÏØ| ´óÍ¬ÏØ| òÔºÓÊÐ| ¾¸½­ÊÐ| Â¡Ò¢ÏØ| Ѱµé| ²©ÂÞÏØ| ÎäÃùÏØ| ÐìÎÅÏØ| ºÍÁúÊÐ| ÀÖ¶¼ÏØ| ÙÙÖÝÊÐ|