狼愛上貍

          我胡漢三又回來了

          #

          acegi,IBM的Acegi Security System(2)

          2007 年 6 月 21 日

          了解了 Acegi 安全系統(tǒng)(Acegi Security System)的 基礎(chǔ)知識(shí) 后,我們將介紹該系統(tǒng)的更加高級(jí)的應(yīng)用。在本文中,Bilal Siddiqui 向您展示了如何結(jié)合使用 Acegi 和一個(gè) LDAP 目錄服務(wù)器,實(shí)現(xiàn)靈活的具有高性能的 Java™ 應(yīng)用程序的安全性。還將了解如何編寫訪問控制策略并將其存儲(chǔ)在 ApacheDS 中,然后配置 Acegi 使其與目錄服務(wù)器交互,從而實(shí)現(xiàn)身份驗(yàn)證和授權(quán)的目的。

          這期共分三部分的系列文章介紹了如何使用 Acegi 安全系統(tǒng)保護(hù) Java 企業(yè)應(yīng)用程序。在 本系列第一篇文章 中,我介紹了 Acegi 并解釋了如何使用安全過濾器實(shí)現(xiàn)一個(gè)簡單的基于 URL 的安全系統(tǒng)。在第二篇文章中,我將討論 Acegi 的更加高級(jí)的應(yīng)用,首先我將編寫一個(gè)訪問控制策略并將其存儲(chǔ)在 ApacheDS 中,ApacheDS 是一個(gè)開源的 LDAP 目錄服務(wù)器。我還將展示配置 Acegi 的方法,使它能夠與目錄服務(wù)器交互并實(shí)現(xiàn)您的訪問控制策略。本文的結(jié)尾提供了一個(gè)示例應(yīng)用程序,它使用 ApacheDS 和 Acegi 實(shí)現(xiàn)了一個(gè)安全的訪問控制策略。

          實(shí)現(xiàn)訪問控制策略通常包含兩個(gè)步驟:

          1. 將有關(guān)用戶和用戶角色的數(shù)據(jù)存儲(chǔ)在目錄服務(wù)器中。
          2. 編寫安全代碼,它將定義有權(quán)訪問并使用數(shù)據(jù)的人員。

          Acegi 將減輕代碼編寫的工作,因此在這篇文章中,我將展示如何將用戶和用戶角色信息存儲(chǔ)到 ApacheDS 中,然后實(shí)現(xiàn)這些信息的訪問控制策略。在該系列的最后一篇文章中,我將展示如何配置 Acegi,實(shí)現(xiàn)對 Java 類的安全訪問。

          您可以在本文的任何位置 下載樣例應(yīng)用程序。參見 參考資料 下載 Acegi、Tomcat 和 ApacheDS,您需要使用它們運(yùn)行樣例代碼和示例應(yīng)用程序。

          LDAP 基礎(chǔ)知識(shí)

          輕量級(jí)目錄訪問協(xié)議(Lightweight Directory Access Protocol,LDAP)可能是最流行的一種定義數(shù)據(jù)格式的協(xié)議,它針對常見的目錄操作,例如對存儲(chǔ)在目錄服務(wù)器中的信息執(zhí)行的讀取、編輯、搜索和刪除操作。本節(jié)將簡要解釋為什么目錄服務(wù)器是屬性文件存儲(chǔ)安全信息的首選,并展示如何在 LDAP 目錄中組織和托管用戶信息。

          為什么要使用目錄服務(wù)器?

          本系列第一部分向您介紹了一種簡單的方法,可以將用戶信息以屬性文件的形式保存起來(參見 第 1 部分,清單 6)。屬性文件以文本格式保存用戶名、密碼和用戶角色。對于大多數(shù)真實(shí)應(yīng)用程序而言,使用屬性文件存儲(chǔ)安全信息遠(yuǎn)遠(yuǎn)不夠。各種各樣的理由表明,目錄服務(wù)器通常都是更好的選擇。其中一個(gè)原因是,真實(shí)的企業(yè)應(yīng)用程序可以被大量用戶訪問 —— 通常是幾千名用戶,如果應(yīng)用程序?qū)⑵洳糠止δ芄_給用戶和供應(yīng)商時(shí)更是如此。頻繁搜索文本文件中隨意存儲(chǔ)的信息,這樣做的效率并不高,但是目錄服務(wù)器對這類搜索進(jìn)行了優(yōu)化。

          第 1 部分的清單 6 中的屬性文件演示了另一個(gè)原因,該文件組合了用戶和角色。在真實(shí)的訪問控制應(yīng)用程序中,您通常都需要分別定義和維護(hù)用戶和角色信息,這樣做可以簡化用戶庫的維護(hù)。目錄服務(wù)器為更改或更新用戶信息提供了極大的靈活性,例如,反映職位升遷或新聘用人員。參見 參考資料 以了解更多關(guān)于目錄服務(wù)器的使用及其優(yōu)點(diǎn)的信息。

          LDAP 目錄設(shè)置

          如果希望將用戶信息存儲(chǔ)在一個(gè) LDAP 目錄中,您需要理解一些有關(guān)目錄設(shè)置的內(nèi)容。本文并沒有提供對 LDAP 的完整介紹(參見 參考資料),而是介紹了一些在嘗試結(jié)合使用 Acegi 和 LDAP 目錄之前需要了解的基本概念。

          LDAP 目錄以節(jié)點(diǎn)樹的形式存儲(chǔ)信息,如圖 1 所示:


          圖 1. LDAP 目錄的樹狀結(jié)構(gòu)
          圖 1. LDAP 目錄的樹狀結(jié)構(gòu)

          在圖 1 中,根節(jié)點(diǎn)的名稱為 org。根節(jié)點(diǎn)可以封裝與不同企業(yè)有關(guān)的數(shù)據(jù)。例如,本系列第 1 部分開發(fā)的制造業(yè)企業(yè)被顯示為 org 節(jié)點(diǎn)的直接子節(jié)點(diǎn)。該制造業(yè)企業(yè)具有兩個(gè)名為 departmentspartners 的子節(jié)點(diǎn)。

          partners 子節(jié)點(diǎn)封裝了不同類型的合作伙伴。圖 1 所示的三個(gè)分別為 customersemployeessuppliers。注意,這三種類型的合作伙伴其行為與企業(yè)系統(tǒng)用戶一樣。每一種類型的用戶所扮演的業(yè)務(wù)角色不同,因此訪問系統(tǒng)的權(quán)利也不同。

          類似地,departments 節(jié)點(diǎn)包含該制造業(yè)企業(yè)的不同部門的數(shù)據(jù) —— 例如 engineeringmarketing 字節(jié)點(diǎn)。每個(gè)部門節(jié)點(diǎn)還包含一組或多組用戶。在 圖 1 中,engineers 組是 engineering 部門的子節(jié)點(diǎn)。

          假設(shè)每個(gè)部門的子節(jié)點(diǎn)表示一組用戶。因此,部門節(jié)點(diǎn)的子節(jié)點(diǎn)具有不同的用戶成員。例如,設(shè)計(jì)部門的所有工程師都是 engineering 部門內(nèi) engineers 組的成員。

          最后,注意 圖 1departments 節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)。specialUser 是一名用戶,而非一組用戶。在目錄設(shè)置中,像 alicebob 之類的用戶一般都包含在 partners 節(jié)點(diǎn)中。我將這個(gè)特殊用戶包含在 departments 節(jié)點(diǎn)中,以此證明 Acegi 允許用戶位于 LADP 目錄中任何地點(diǎn)的靈活性。稍后在本文中,您將了解如何配置 Acegi 以應(yīng)用 specialUser

          使用專有名稱

          LDAP 使用專有名稱(DN)的概念來識(shí)別 LDAP 樹上特定的節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)具有惟一的 DN,它包含該節(jié)點(diǎn)完整的層次結(jié)構(gòu)信息。例如,圖 2 展示了圖 1 中的一些節(jié)點(diǎn)的 DN:


          圖 2. LDAP 目錄節(jié)點(diǎn)的專有名稱
          圖 2. LDAP 目錄節(jié)點(diǎn)的專有名稱

          首先,注意圖 2 中根節(jié)點(diǎn)的 DN。它的 DN 為 dc=org,這是與 org 根節(jié)點(diǎn)相關(guān)的屬性值對。每個(gè)節(jié)點(diǎn)都有若干個(gè)與之相關(guān)的屬性。dc 屬性代表 “domain component” 并由 LDAP RFC 2256 定義(參見 參考資料 中有關(guān)官方 RFC 文檔的鏈接),LDAP 目錄中的根節(jié)點(diǎn)通常表示為一個(gè)域組件。

          每個(gè) LDAP 屬性是由 RFC 定義的。LDAP 允許使用多個(gè)屬性創(chuàng)建一個(gè) DN,但是本文的示例只使用了以下 4 個(gè)屬性:

          • dc(域組件)
          • o(組織)
          • ou(組織單元)
          • uid(用戶 ID)

          示例使用 dc 表示域,用 o 表示組織名稱,ou 表示組織的不同單元,而 uid 表示用戶。

          由于 org 是根節(jié)點(diǎn),其 DN 只需指定自身的名稱(dc=org)。比較一下,manufacturingEnterprise 節(jié)點(diǎn)的 DN 是 o=manufacturingEnterprise,dc=org。當(dāng)向下移動(dòng)節(jié)點(diǎn)樹時(shí),每個(gè)父節(jié)點(diǎn)的 DN 被包含在其子節(jié)點(diǎn)的 DN 中。

          將屬性分組

          LDAP 將相關(guān)的屬性類型分到對象類中。例如,名為 organizationalPerson 的對象類所包含的屬性定義了在組織內(nèi)工作的人員(例如,職稱、常用名、郵寄地址等等)。

          對象類使用繼承特性,這意味著 LDAP 定義了基類來保存常用屬性。然后子類再對基類進(jìn)行擴(kuò)展,使用其定義的屬性。LDAP 目錄中的單個(gè)節(jié)點(diǎn)可以使用若干個(gè)對象類:本文的示例使用了以下幾個(gè)對象類:

          • top 對象類是 LDAP 中所有對象類的基類。

          • 當(dāng)其他對象類都不適合某個(gè)對象時(shí),將使用 domain 對象類。它定義了一組屬性,任何一個(gè)屬性都可以用來指定一個(gè)對象。其 dc 屬性是強(qiáng)制性的。

          • organization 對象類表示組織節(jié)點(diǎn),例如 圖 2 中的 manufacturingEnterprise

          • organizationalUnit 對象類表示組織內(nèi)的單元,例如 圖 1 中的 departments 節(jié)點(diǎn)及其子節(jié)點(diǎn)。

          • groupOfNames 對象類表示一組名稱,例如某部門職員的名稱。它具有一個(gè) member 屬性,該屬性包含一個(gè)用戶列表。圖 1 中所有的組節(jié)點(diǎn)(例如 engineers 節(jié)點(diǎn))使用 member 屬性指定該組的成員。而且,示例使用 groupOfNames 對象類的 ou(組織單元)屬性指定組用戶的業(yè)務(wù)角色。

          • organizationalPerson 對象類表示組織內(nèi)某個(gè)職員(例如 圖 1 中的 alice 節(jié)點(diǎn))。




          回頁首


          使用 LDAP 服務(wù)器

          在真實(shí)的應(yīng)用程序中,通常將有關(guān)系統(tǒng)用戶的大量信息托管在一個(gè) LDAP 目錄中。例如,將存儲(chǔ)每個(gè)用戶的用戶名、密碼、職稱、聯(lián)系方式和工資信息。為簡單起見,下面的例子將只向您展示如何保存用戶名和密碼。

          如前所述,示例使用 ApacheDS(一種開源的 LDAP 目錄服務(wù)器)演示了 Acegi 是如何使用 LDAP 目錄的。示例還使用了一個(gè)開源的 LDAP 客戶機(jī)(名為 JXplorer)執(zhí)行簡單的目錄操作,例如將信息托管在 ApacheDS 上。參見 參考資料 以下載 ApacheDS、JXplorer 并了解更多有關(guān)兩者協(xié)作的信息。

          在 ApacheDS 創(chuàng)建一個(gè)根節(jié)點(diǎn)

          要?jiǎng)?chuàng)建 圖 1 所示的節(jié)點(diǎn)樹,必須首先在 ApacheDS 中創(chuàng)建一個(gè)根節(jié)點(diǎn) org。ApacheDS 為此提供了一個(gè) XML 配置文件。XML 配置文件定義了一組可進(jìn)行配置的 bean,從而根據(jù)應(yīng)用程序的需求定制目錄服務(wù)器的行為。本文只解釋創(chuàng)建根節(jié)點(diǎn)所需的配置。

          可以在 ApacheDS 安裝中的 conf 文件夾找到名為 server.xml 的 XML 配置文件。打開文件后,會(huì)發(fā)現(xiàn)很多 bean 配置類似于 Acegi 的過濾器配置。查找名為 examplePartitionsConfiguration 的 bean。該 bean 控制 ApacheDS 上的分區(qū)。當(dāng)創(chuàng)建新的根節(jié)點(diǎn)時(shí),實(shí)際上將在 LDAP 目錄上創(chuàng)建一個(gè)新的分區(qū)。

          編輯 examplePartitionConfiguration bean 以創(chuàng)建 org 根節(jié)點(diǎn),如清單 1 所示:


          清單 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 的兩個(gè)屬性:

          • 一個(gè)屬性名為 suffix,它定義根條目的 DN。

          • 另一個(gè)屬性名為 contextEntry,定義 org 節(jié)點(diǎn)將使用的對象類。注意,org 根節(jié)點(diǎn)使用兩個(gè)對象類:topdomain

          本文的 源代碼下載 部分包含了編輯模式的 server.xml 文件。如果希望繼續(xù)學(xué)習(xí)本示例,請將 server.xml 文件從源代碼中復(fù)制到您的 ApacheDS 安裝目錄中的正確位置,即 conf 文件夾。

          圖 3 所示的屏幕截圖展示了在 ApacheDS 中創(chuàng)建根節(jié)點(diǎn)后,JXplorer 是如何顯示該根節(jié)點(diǎn)的:


          圖 3. JXplorer 顯示根節(jié)點(diǎn)
          圖 3. JXplorer 顯示根節(jié)點(diǎn)

          填充服務(wù)器

          設(shè)置 LDAP 服務(wù)器的下一步是使用用戶和組信息填充服務(wù)器。您可以使用 JXplorer 在 ApacheDS 中逐個(gè)創(chuàng)建節(jié)點(diǎn),但是使用 LDAP Data Interchange Format (LDIF) 填充服務(wù)器會(huì)更加方便。LDIF 是可被大多數(shù) LDAP 實(shí)現(xiàn)識(shí)別的常見格式。developerWorks 文章很好地介紹了 LDIF 文件的內(nèi)容,因此本文將不再做詳細(xì)說明。(參見 參考資料 中有關(guān) LDIF 的詳細(xì)資料。)

          您可以在 源代碼下載 部分查看 LDIF 文件,它表示 圖 1 所示的用戶和部門。您可以使用 JXplorer 將 LDIF 文件導(dǎo)入到 ApacheDS。要導(dǎo)入 LDIF 文件,在 JXplorer 中使用 LDIF 菜單,如圖 4 所示:


          圖 4. 將 LDIF 文件導(dǎo)入到 ApacheDS
          圖 4. 將 LDIF 文件導(dǎo)入到 ApacheDS

          將 LDIF 文件導(dǎo)入到 ApacheDS 之后,JXplorer 將顯示用戶節(jié)點(diǎn)和部門節(jié)點(diǎn)樹,如 圖 1 所示。現(xiàn)在您可以開始配置 Acegi,使其能夠與您的 LDAP 服務(wù)器通信。





          回頁首


          為 LDAP 實(shí)現(xiàn)配置 Acegi

          回想一下第 1 部分,其中 Acegi 使用身份驗(yàn)證處理過濾器(Authentication Processing Filter,APF)進(jìn)行身份驗(yàn)證。APF 執(zhí)行所有后端身份驗(yàn)證處理任務(wù),例如從客戶機(jī)請求中提取用戶名和密碼,從后端用戶庫讀取用戶參數(shù),以及使用這些信息對用戶進(jìn)行身份驗(yàn)證。

          您在第 1 部分中為屬性文件實(shí)現(xiàn)配置了 APF,現(xiàn)在您已將用戶庫存儲(chǔ)在 LDAP 目錄中,因此必須使用不同的方式配置過濾器來和 LDAP 目錄進(jìn)行通信。首先看一下清單 2,它展示了在第 1 部分中的 “Authentication Processing Filter” 一節(jié)中如何為屬性文件實(shí)現(xiàn)配置 APF 過濾器:


          清單 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,您曾經(jīng)為 APF 提供了 4 個(gè)參數(shù)。您只需在 LDAP 服務(wù)器中為存儲(chǔ)重新配置第一個(gè)參數(shù)(authenticationManager)即可。其他三個(gè)參數(shù)保持不變。

          配置身份驗(yàn)證管理器

          清單 3 展示了如何配置 Acegi 的身份驗(yàn)證管理器,以實(shí)現(xiàn)與 LDAP 服務(wù)器的通信:


          清單 3. 為 LDAP 配置 Acegi 的身份驗(yàn)證管理器
                                  <bean id="authenticationManager"
                      class="org.acegisecurity.providers.ProviderManager">
                      <property name="providers">
                      <list>
                      <ref local="ldapAuthenticationProvider" />
                      </list>
                      </property>
                      </bean>
                      

          在清單 3 中,org.acegisecurity.providers.ProviderManager 是一個(gè)管理器類,它管理 Acegi 的身份驗(yàn)證過程。為此,身份驗(yàn)證管理器需要一個(gè)或多個(gè)身份驗(yàn)證提供者。您可以使用管理器 bean 的提供者屬性來配置一個(gè)或多個(gè)提供者。清單 3 只包含了一個(gè)提供者,即 LDAP 身份驗(yàn)證提供者。

          LDAP 身份驗(yàn)證提供者處理所有與后端 LDAP 目錄的通信。您必須對其進(jìn)行配置,下一節(jié)內(nèi)容將討論該主題。

          配置 LDAP 身份驗(yàn)證提供者

          清單 4 展示了 LDAP 身份驗(yàn)證提供者的配置:


          清單 4. 配置 LDAP 身份驗(yàn)證提供者
                                  <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 身份驗(yàn)證提供者類的名稱為 org.acegisecurity.providers.ldap.LdapAuthenticationProvider 。其構(gòu)造函數(shù)包含兩個(gè)參數(shù),使用兩個(gè) <constructor-arg> 標(biāo)記的形式,如清單 4 所示。

          LdapAuthenticationProvider 構(gòu)造函數(shù)的第一個(gè)參數(shù)是 authenticator,該參數(shù)通過檢查用戶的用戶名和密碼對 LDAP 目錄的用戶進(jìn)行身份驗(yàn)證。完成身份驗(yàn)證后,第二個(gè)參數(shù) populator 將從 LDAP 目錄中檢索有關(guān)該用戶的訪問權(quán)限(或業(yè)務(wù)角色)信息。

          以下小節(jié)將向您展示如何配置驗(yàn)證器和填充器 bean。





          回頁首


          配置驗(yàn)證器

          authenticator bean 將檢查具有給定用戶名和密碼的用戶是否存在于 LDAP 目錄中。Acegi 提供了名為 org.acegisecurity.providers.ldap.authenticator.BindAuthenticator 的驗(yàn)證器類,它將執(zhí)行驗(yàn)證用戶名和密碼所需的功能。

          配置 authenticator bean,如清單 5 所示:


          清單 5. 配置驗(yàn)證器 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 構(gòu)造函數(shù)具有一個(gè)參數(shù),使用 <constructor-arg> 標(biāo)記的形式。清單 5 中參數(shù)的名稱為 initialDirContextFactory。該參數(shù)實(shí)際上是另一個(gè) bean,稍后您將學(xué)習(xí)如何配置該 bean。

          目前為止,只知道 initialDirContextFactory bean 的作用就是為稍后的搜索操作指定初始上下文。初始上下文是一個(gè) DN,它指定了 LDAP 目錄內(nèi)某個(gè)節(jié)點(diǎn)。指定初始上下文后,將在該節(jié)點(diǎn)的子節(jié)點(diǎn)中執(zhí)行所有的搜索操作(例如查找特定用戶)。

          例如,回到 圖 2 中查看 partners 節(jié)點(diǎn),它的 DN 是 ou=partners,o=manufacturingEnterprise,dc=org。如果將 partners 節(jié)點(diǎn)指定為初始上下文,Acegi 將只在 partners 節(jié)點(diǎn)的子節(jié)點(diǎn)中查找用戶。

          指定 DN 模式

          除配置 BindAuthenticator 構(gòu)造函數(shù)外,還必須配置 authenticator bean 的兩個(gè)屬性(清單 5 中的兩個(gè) <property> 標(biāo)記)。

          第一個(gè) <property> 標(biāo)記定義了一個(gè) userDnPatterns 屬性,它封裝了一個(gè)或多個(gè) DN 模式列表。DN 模式 指定了一組具有類似特性的 LDAP 節(jié)點(diǎn)(例如 圖 2 所示的 employees 節(jié)點(diǎn)的所有子節(jié)點(diǎn))。

          Acegi 的身份驗(yàn)證器從 authenticator bean 的 userDnPatterns 屬性中配置的每個(gè) DN 模式構(gòu)造了一個(gè) DN。例如,查看 清單 5 中配置的第一個(gè)模式,即 uid={0},ou=employees,ou=partners。在進(jìn)行身份驗(yàn)證的時(shí)候,authenticator bean 使用用戶提供的用戶名(比如 alice)替換了 {0}。使用用戶名取代了 {0} 之后,DN 模式將變?yōu)橄鄬?DN(RDN)uid=alice,ou=employees,ou=partners,它需要一個(gè)初始上下文才能成為 DN。

          例如,查看 圖 2 中的 alice's 條目。該條目是 employees 節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)。它的 DN 是 uid=alice,ou=employees,ou=partners,o=manufacturingEnterprise, dc=org。如果使用 o=manufacturingEnterprise,dc=org 作為初始上下文并將其添加到 RDN uid=alice,ou=employees,ou=partners 之后,將獲得 alice 的 DN。

          使用這種方法通過 DN 模式構(gòu)建了用戶的 DN 后,authenticator 將把 DN 和用戶密碼發(fā)送到 LDAP 目錄。目錄將檢查該 DN 是否具有正確的密碼。如果有的話,用戶就可以通過身份驗(yàn)證。這個(gè)過程在 LDAP 術(shù)語中被稱為 bind 身份驗(yàn)證。LDAP 還提供了其他類型的身份驗(yàn)證機(jī)制,但是本文的示例只使用了 bind 身份驗(yàn)證。

          如果目錄中并沒有第一個(gè) DN 模式創(chuàng)建的 DN,authenticator bean 嘗試使用列表中配置的第二個(gè) DN 模式。依此類推,authenticator bean 將嘗試所有的 DN 模式來為進(jìn)行身份驗(yàn)證的用戶構(gòu)造正確的用戶 DN。

          搜索過濾器

          回想一下較早的章節(jié) “LDAP 目錄設(shè)置”,我在將用戶信息存儲(chǔ)到 LDAP 目錄時(shí)添加了一點(diǎn)靈活性。方法是在 圖 1 所示的 departments 節(jié)點(diǎn)內(nèi)創(chuàng)建一個(gè)特定用戶(specialUser)。

          如果試圖使用 清單 5 中配置的任何一種 DN 模式創(chuàng)建特定用戶的 DN,您會(huì)發(fā)現(xiàn)沒有一種 DN 模式可用。因此,當(dāng)用戶嘗試登錄時(shí),Acegi 的 authenticator bean 將不能夠構(gòu)造正確的 DN,從而無法對該用戶進(jìn)行身份驗(yàn)證。

          通過允許您指定搜索過濾器,Acegi 能夠處理類似的特殊情況。身份驗(yàn)證器 bean 使用搜索過濾器查找不能夠通過 DN 模式構(gòu)造 DN 進(jìn)行身份驗(yàn)證的用戶。

          清單 5 中的第二個(gè) <property> 標(biāo)記具有一個(gè) <ref> 子標(biāo)記,它引用名為 userSearch 的 bean。userSearch bean 指定搜索查詢。清單 6 展示了如何配置 userSearch bean 來處理特定用戶:


          清單 6. 配置搜索查詢以搜索特定用戶
                                  <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>
                      

          搜索查詢的參數(shù)

          清單 6 展示了 userSearch bean 是 org.acegisecurity.ldap.search.FilterBasedLdapUserSearch 類的一個(gè)實(shí)例,該類的構(gòu)造函數(shù)具有三個(gè)參數(shù)。第一個(gè)參數(shù)指定 authenticator 在哪個(gè)節(jié)點(diǎn)中搜索用戶。第一個(gè)參數(shù)的值為 ou=departments,該值是一個(gè) RDN,指定了 圖 2 所示的 departments 節(jié)點(diǎn)。

          第二個(gè)參數(shù) (uid={0}) 指定了一個(gè)搜索過濾器。由于使用 uid 屬性指定用戶,因此可以通過查找 uid 屬性具有特定值的節(jié)點(diǎn)來查找用戶。正如您所料,花括號(hào)里面的 0 向 Acegi 表示使用進(jìn)行身份驗(yàn)證的用戶的用戶名(本例中為 specialUser)替換 {0}

          第三個(gè)參數(shù)是對討論 清單 5 中的 BindAuthenticator 構(gòu)造函數(shù)時(shí)引入的相同初始上下文的引用。回想一下,當(dāng)指定了初始上下文后,稍后將在該初始上下文節(jié)點(diǎn)的子節(jié)點(diǎn)內(nèi)進(jìn)行所有的搜索操作。注意,應(yīng)將指定為 清單 5 中第一個(gè)參數(shù)(ou=departments)的值的 RDN 前加到初始上下文。

          除了這三個(gè)構(gòu)造器參數(shù),清單 6 所示的 userSearch bean 還具有一個(gè)名為 searchSubtree 的屬性。如果將其值指定為 true,搜索操作將包括節(jié)點(diǎn)的子樹(即所有子節(jié)點(diǎn)、孫節(jié)點(diǎn)、孫節(jié)點(diǎn)的子節(jié)點(diǎn)等),該節(jié)點(diǎn)被指定為構(gòu)造函數(shù)的第一個(gè)參數(shù)的值。

          authenticator bean 的配置完成后,下一步將查看 populator bean 的配置,如 清單 4 所示。





          回頁首


          配置 populator

          populator bean 將讀取已經(jīng)通過 authenticator bean 身份驗(yàn)證的用戶的業(yè)務(wù)角色。清單 7 展示 populator bean 的 XML 配置:


          清單 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 的構(gòu)造函數(shù)包括 2 個(gè)參數(shù),以及一個(gè) groupRoleAttribute 屬性。構(gòu)造函數(shù)的第一個(gè)參數(shù)指定了 populator bean 用來讀取經(jīng)過驗(yàn)證用戶的業(yè)務(wù)角色的初始上下文。并不強(qiáng)制要求 authenticatorpopulator bean 使用相同的初始上下文。您可以為這兩者分別配置一個(gè)初始上下文。

          第二個(gè)構(gòu)造函數(shù)參數(shù)指定了 populator 前加到初始上下文的 RDN。因此,RDN 組成了包含組用戶的節(jié)點(diǎn)的 DN,例如 departments 節(jié)點(diǎn)。

          populator bean 的 groupRoleAttribute 屬性指定了持有組成員業(yè)務(wù)角色數(shù)據(jù)的屬性。回想 設(shè)置 LDAP 目錄 一節(jié)中,您將每組用戶的業(yè)務(wù)角色信息存儲(chǔ)在名為 ou 的屬性中。然后將 ou 設(shè)置為 groupRoleAttribute 屬性的值,如 清單 7 所示。

          如您所料,populator bean 將搜索整個(gè) LDAP 目錄來查找經(jīng)過驗(yàn)證的用戶所屬的組節(jié)點(diǎn)。然后讀取組節(jié)點(diǎn)的 ou 屬性的值,獲取用戶經(jīng)過授權(quán)的業(yè)務(wù)角色。

          這樣就完成了 populator bean 的配置。目前為止,我們在三個(gè)位置使用了初始上下文:清單 5清單 6清單 7。接下來將了解如何配置初始上下文。

          配置初始上下文

          清單 8 展示了在 Acegi 中配置初始上下文的過程:


          清單 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 的初始上下文類的名稱為 org.acegisecurity.ldap.DefaultInitialDirContextFactory,這是 Acegi 包含的工廠類。Acegi 在內(nèi)部使用該類構(gòu)造其他處理目錄操作(例如在整個(gè)目錄中搜索)的類的對象。當(dāng)配置初始上下文工廠時(shí),必須指定以下內(nèi)容:

          • 將您的 LDAP 目錄和根目錄節(jié)點(diǎn)的網(wǎng)絡(luò)地址指定為構(gòu)造函數(shù)的參數(shù)。在初始上下文配置的節(jié)點(diǎn)將作為根節(jié)點(diǎn)。就是說所有后續(xù)操作(例如 search)都將在根節(jié)點(diǎn)定義的子樹中執(zhí)行。

          • 將 DN 和密碼分別定義為 managerDnmanagerPassword 屬性。在執(zhí)行任何搜索操作之前,Acegi 必須使用目錄服務(wù)器對 DN 和密碼進(jìn)行身份驗(yàn)證。

          您已經(jīng)了解了如何將用戶庫托管在 LDAP 目錄中,以及如何配置 Acegi 來使用來自 LDAP 目錄的信息對用戶進(jìn)行身份驗(yàn)證。下一節(jié)將進(jìn)一步介紹 Acegi 的身份驗(yàn)證處理過濾器,了解新配置的 bean 是如何管理身份驗(yàn)證過程的。





          回頁首


          身份驗(yàn)證和授權(quán)

          APF 配置完成后,將能夠與 LDAP 目錄進(jìn)行通信來對用戶進(jìn)行身份驗(yàn)證。如果您閱讀過第 1 部分,那么對與目錄通信過程中 APF 執(zhí)行的一些步驟不會(huì)感到陌生,我在第 1 部分中向您展示了過濾器如何使用不同的服務(wù)進(jìn)行用戶身份驗(yàn)證。圖 5 所示的序列表與您在 第 1 部分圖 3 看到的非常類似:


          圖 5. APF 對一名 LDAP 用戶進(jìn)行身份驗(yàn)證
          圖 5. APF 對一名 LDAP 用戶進(jìn)行身份驗(yàn)證

          無論 APF 使用屬性文件進(jìn)行內(nèi)部的身份驗(yàn)證還是與 LDAP 服務(wù)器進(jìn)行通信,步驟 1 到步驟 9 與第 1 部分是相同的。這里簡單描述了前 9 個(gè)步驟,您可以從步驟 10 開始繼續(xù)學(xué)習(xí)特定于 LDAP 的事件:

          1. 過濾器鏈前面的過濾器將請求、響應(yīng)和過濾器鏈對象傳遞給 APF。

          2. APF 使用取自請求對象的用戶名、密碼和其他信息創(chuàng)建一個(gè)身份驗(yàn)證標(biāo)記。

          3. APF 將身份驗(yàn)證標(biāo)記傳遞給身份驗(yàn)證管理器。

          4. 身份驗(yàn)證管理器可能包含一個(gè)或多個(gè)身份驗(yàn)證提供者。每個(gè)提供者恰好支持一種身份驗(yàn)證類型。管理器將檢查哪一種提供者支持從 APF 接收到的身份驗(yàn)證標(biāo)記。

          5. 身份驗(yàn)證管理器將身份驗(yàn)證標(biāo)記傳遞給適合該類型身份驗(yàn)證的提供者。

          6. 身份驗(yàn)證提供者從身份驗(yàn)證標(biāo)記中提取用戶名并將其傳遞到名為 user cache service 的服務(wù)。Acegi 緩存了已經(jīng)進(jìn)行過身份驗(yàn)證的用戶。該用戶下次登錄時(shí),Acegi 可以從緩存中加載他或她的詳細(xì)信息(比如用戶名、密碼和權(quán)限),而不是從后端數(shù)據(jù)存儲(chǔ)中讀取數(shù)據(jù)。這種方法使得性能得到了改善。

          7. user cache service 檢查用戶的詳細(xì)信息是否存在于緩存中。

          8. user cache service 將用戶的詳細(xì)信息返回給身份驗(yàn)證提供者。如果緩存不包含用戶詳細(xì)信息,則返回 null。

          9. 身份驗(yàn)證提供者檢查緩存服務(wù)返回的是用戶的詳細(xì)信息還是 null。

          10. 從這里開始,身份驗(yàn)證處理將特定于 LDAP。 如果緩存返回 null,LDAP 身份驗(yàn)證提供者將把用戶名(在步驟 6 中提取的)和密碼傳遞給 清單 5 中配置的 authenticator bean。

          11. authenticator 將使用在 清單 5userDnPatterns 屬性中配置的 DN 模式創(chuàng)建用戶 DN。通過從一個(gè) DN 模式中創(chuàng)建一個(gè) DN,然后將該 DN 和用戶密碼(從用戶請求中獲得)發(fā)送到 LDAP 目錄,它將逐一嘗試所有可用的 DN 模式。LDAP 目錄將檢查該 DN 是否存在以及密碼是否正確。如果其中任何一個(gè) DN 模式可行的話,用戶被綁定到 LDAP 目錄中,authenticator 將繼續(xù)執(zhí)行步驟 15。

          12. 如果任何一種 DN 模式都不能工作的話(這意味著在 DN 模式指定的任何位置都不存在使用給定密碼的用戶),authenticator 根據(jù) 清單 6 配置的搜索查詢在 LDAP 目錄中搜索用戶。如果 LDAP 目錄沒有找到用戶,那么身份驗(yàn)證以失敗告終。

          13. 如果 LDAP 目錄查找到了用戶,它將用戶的 DN 返回到 authenticator

          14. authenticator 將用戶 DN 和密碼發(fā)送到 LDAP 目錄來檢查用戶密碼是否正確。如果 LDAP 目錄發(fā)現(xiàn)用戶密碼是正確的,該用戶將被綁定到 LDAP 目錄。

          15. authenticator 將用戶信息發(fā)送回 LDAP 身份驗(yàn)證提供者。

          16. LDAP 身份驗(yàn)證提供者將控制權(quán)傳遞給 populator bean。

          17. populator 搜索用戶所屬的組。

          18. LDAP 目錄將用戶角色信息返回給 populator

          19. populator 將用戶角色信息返回給 LDAP 身份驗(yàn)證提供者。

          20. LDAP 身份驗(yàn)證提供者將用戶的詳細(xì)信息(以及用戶業(yè)務(wù)角色信息)返回給 APF。用戶現(xiàn)在成功進(jìn)行了身份驗(yàn)證。

          不論使用何種身份驗(yàn)證方法,最后三個(gè)步驟是相同的(步驟21、21 和 23)。

          配置攔截器

          您已經(jīng)了解了 APF 對用戶進(jìn)行身份驗(yàn)證的步驟。接下來是查看成功進(jìn)行身份驗(yàn)證的用戶是否被授權(quán)訪問所請求的資源。這項(xiàng)任務(wù)由 Acegi 的攔截過濾器(Interceptor Filter,IF)完成。本節(jié)將向您展示如何配置 IF 來實(shí)現(xiàn)訪問控制策略。

          回想一下在 第 1 部分的清單 7 中配置 IF 的步驟。攔截過濾器在資源和角色之間建立映射,就是說只有具備必要角色的用戶才能訪問給定資源。為了演示制造業(yè)企業(yè)中不同部門的業(yè)務(wù)角色,清單 9 向現(xiàn)有的 IF 配置添加了另外的角色:


          清單 9. 配置攔截過濾器
                                  <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 包含三個(gè)參數(shù)。其中第一個(gè)和第三個(gè)參數(shù)與第 1 部分中最初配置的參數(shù)相同。這里添加了第二個(gè)參數(shù)(名為 accessDecisionManager 的 bean)。

          accessDecisionManager bean 負(fù)責(zé)指定授權(quán)決策。它使用清單 9 中第三個(gè)參數(shù)提供的訪問控制定義來指定授權(quán)(或訪問控制)決策。第三個(gè)參數(shù)是 objectDefinitionSource

          配置訪問決策管理器

          accessDecisionManager 決定是否允許一個(gè)用戶訪問某個(gè)資源。Acegi 提供了一些訪問決策管理器,它們指定訪問控制決策的方式有所不同。本文只解釋了其中一種訪問決策管理器的工作方式,其配置如清單 10 所示:


          清單 10. 配置訪問決策管理器
                                  <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 類的實(shí)例。accessDecisionManager bean 只包含一個(gè)參數(shù),即投票者(voter)列表。

          在 Acegi 中,投票者確定是否允許某個(gè)用戶訪問特定的資源。當(dāng)使用 accessDecisionManager 查詢時(shí),投票者具有三個(gè)選項(xiàng):允許訪問(access-granted)、拒絕訪問(access-denied),如果不確定的話則放棄投票(abstain from voting)。

          不同類型的訪問決策管理器解釋投票者決策的方法也有所不同。清單 10 所示的 AffirmativeBased 訪問決策管理器實(shí)現(xiàn)了簡單的決策邏輯:如果任何投票者強(qiáng)制執(zhí)行肯定投票,將允許用戶訪問所請求的資源。

          投票者邏輯

          Acegi 提供了若干個(gè)投票者實(shí)現(xiàn)類型。accessDecisionManager 將經(jīng)過驗(yàn)證的用戶的信息(包括用戶的業(yè)務(wù)角色信息)和 objectDefinitionSource 對象傳遞給投票者。本文的示例使用了兩種類型的投票者,RoleVoterAuthenticatedVoter,如清單 10 所示。現(xiàn)在看一下每種投票者的邏輯:

          • RoleVoter 只有在 objectDefinitionSource 對象的行中找到以 ROLE_ 前綴開頭的角色時(shí)才進(jìn)行投票。如果 RoleVoter 沒有找到這樣的行,將放棄投票;如果在用戶業(yè)務(wù)角色中找到一個(gè)匹配的角色,它將投票給允許訪問;如果沒有找到匹配的角色,則投票給拒絕訪問。在 清單 9 中,有兩個(gè)角色具有 ROLE_ 前綴:ROLE_HEAD_OF_ENGINEERINGROLE_HEAD_OF_MARKETING

          • AuthenticatedVoter 只有在 objectDefinitionSource 對象中找到具有某個(gè)預(yù)定義角色的行時(shí)才進(jìn)行投票。在 清單 9 中,有這樣一行:IS_AUTHENTICATED_ANONYMOUSLY。匿名身份驗(yàn)證意味著用戶不能夠進(jìn)行身份驗(yàn)證。找到該行后,AuthenticatedVoter 將檢查一個(gè)匿名身份驗(yàn)證的用戶是否可以訪問某些不受保護(hù)的資源(即這些資源沒有包含在具備 ROLE_ 前綴的行中)。如果 AuthenticatedVoter 發(fā)現(xiàn)所請求的資源是不受保護(hù)的并且 objectDefinitionSource 對象允許匿名身份驗(yàn)證的用戶訪問不受保護(hù)的資源,它將投票給允許訪問;否則就投票給拒絕訪問。




          回頁首


          示例應(yīng)用程序

          本文提供了一個(gè)示例應(yīng)用程序,它將演示您目前掌握的 LDAP 和 Acegi 概念。LDAP-Acegi 應(yīng)用程序?qū)@示一個(gè)索引頁面,該頁面將設(shè)計(jì)和銷售文檔呈現(xiàn)給合適的經(jīng)過身份驗(yàn)證的用戶。正如您將看到的一樣,LDAP-Acegi 應(yīng)用程序允許用戶 alice 查看設(shè)計(jì)文檔,并允許用戶 bob 查看銷售文檔。它還允許特定用戶同時(shí)查看設(shè)計(jì)和銷售文檔。所有這些內(nèi)容都是在本文開頭配置 LDAP 目錄服務(wù)器時(shí)設(shè)置的。立即 下載示例應(yīng)用程序 來開始使用它。





          回頁首


          結(jié)束語

          在本文中,您了解了如何將用戶和業(yè)務(wù)角色信息托管在 LDAP 目錄中。您還詳細(xì)了解了配置 Acegi 的方法,從而與 LDAP 目錄交互實(shí)現(xiàn)訪問控制策略。在本系列最后一期文章中,我將展示如何配置 Acegi 來保護(hù)對 Java 類的訪問。



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

          posted @ 2008-05-08 18:43 狼愛上貍 閱讀(321) | 評(píng)論 (0)編輯 收藏

          acegi,IBM的Acegi Security System(1)

          2007 年 5 月 08 日

          這份共分三部分的系列文章介紹了 Acegi 安全系統(tǒng)(Acegi Security System),它是用于 Java™ 企業(yè)應(yīng)用程序的強(qiáng)大的開源安全框架。在第一篇文章中,Bilal Siddiqui 顧問將向您介紹 Acegi 的架構(gòu)和組件,并展示如何使用它來保護(hù)一個(gè)簡單的 Java 企業(yè)應(yīng)用程序。

          Acegi Security System 是一種功能強(qiáng)大并易于使用的替代性方案,使您不必再為 Java 企業(yè)應(yīng)用程序編寫大量的安全代碼。雖然它專門針對使用 Spring 框架編寫的應(yīng)用程序,但是任何類型的 Java 應(yīng)用程序都沒有理由不去使用 Acegi。這份共分三部分的系列文章詳細(xì)介紹了 Acegi,并展示了如何使用它保護(hù)簡單的企業(yè)應(yīng)用程序以及更復(fù)雜的應(yīng)用程序。

          本系列首先介紹企業(yè)應(yīng)用程序中常見的安全問題,并說明 Acegi 如何解決這些問題。您將了解 Acegi 的架構(gòu)模型及其安全過濾器,后者包含了在保護(hù)應(yīng)用程序中將用到的大多數(shù)功能。您還將了解到各個(gè)過濾器如何單獨(dú)進(jìn)行工作,如何將它們組合起來,以及過濾器如何在一個(gè)企業(yè)安全實(shí)現(xiàn)中將各種功能從頭到尾地鏈接起來。本文最后通過一個(gè)樣例應(yīng)用程序演示了基于 URL 安全系統(tǒng)的 Acegi 實(shí)現(xiàn)。本系列后續(xù)兩篇文章將探究 Acegi 的一些更高級(jí)的應(yīng)用,包括如何設(shè)計(jì)和托管訪問控制策略,然后如何去配置 Acegi 以使用這些策略。

          您必須 下載 Acegi,這樣才能編譯本文的示例代碼并運(yùn)行本文的樣例應(yīng)用程序。還必須有作為工作站的一部分運(yùn)行的 Tomcat 服務(wù)器。

          企業(yè)應(yīng)用程序安全性

          由于企業(yè)內(nèi)容管理(ECM)應(yīng)用程序管理存儲(chǔ)在不同類型數(shù)據(jù)源(如文件系統(tǒng)、關(guān)系數(shù)據(jù)庫和目錄服務(wù))中的企業(yè)內(nèi)容的編寫和處理,ECM 安全性要求對這些數(shù)據(jù)源的訪問進(jìn)行控制。比如,一個(gè) ECM 應(yīng)用程序可能會(huì)控制被授權(quán)讀取、編輯或刪除數(shù)據(jù)的對象,而這些數(shù)據(jù)和制造業(yè)企業(yè)的設(shè)計(jì)、市場營銷、生產(chǎn)以及質(zhì)量控制有關(guān)。

          在一個(gè) ECM 安全場景中,比較常見的就是通過對企業(yè)資源定位符(或網(wǎng)絡(luò)地址)應(yīng)用安全性,從而實(shí)現(xiàn)訪問控制。這種簡單的安全模型被稱為統(tǒng)一資源定位符 或 URL 安全性。正如我在本文后面(以及本系列后續(xù)文章)所演示的一樣,Acegi 為實(shí)現(xiàn) URL 安全性提供了全面的特性。

          然而,在很多企業(yè)場景中,URL 安全性還遠(yuǎn)遠(yuǎn)不夠。比如,假設(shè)一個(gè) PDF 文檔包含某個(gè)制造業(yè)公司生產(chǎn)的特殊產(chǎn)品的數(shù)據(jù)。文檔的一部分包含了將由該公司的設(shè)計(jì)部門編輯和更新的設(shè)計(jì)數(shù)據(jù)。另一部分包含了生產(chǎn)經(jīng)理將使用的生產(chǎn)數(shù)據(jù)。對于諸如此類的場景,需要實(shí)現(xiàn)更加細(xì)粒度的安全性,對文檔的不同部分應(yīng)用不同的訪問權(quán)限。

          本文介紹了 Acegi 為實(shí)現(xiàn) URL 安全性而提供的各種功能。本系列的下一篇文章將演示此框架的基于方法的安全性,它提供了對企業(yè)數(shù)據(jù)訪問的更細(xì)粒度的控制。





          回頁首


          Acegi Security System

          Acegi Security System 使用安全過濾器來提供企業(yè)應(yīng)用程序的身份驗(yàn)證和授權(quán)服務(wù)。該框架提供了不同類型的過濾器,可以根據(jù)應(yīng)用程序的需求進(jìn)行配置。您將在本文后面了解到 安全過濾器的不同類型;現(xiàn)在,只需注意可以為如下任務(wù)配置 Acegi 安全過濾器:

          1. 在訪問一個(gè)安全資源之前提示用戶登錄。

          2. 通過檢查安全標(biāo)記(如密碼),對用戶進(jìn)行身份驗(yàn)證。

          3. 檢查經(jīng)過身份驗(yàn)證的用戶是否具有訪問某個(gè)安全資源的特權(quán)。

          4. 將成功進(jìn)行身份驗(yàn)證和授權(quán)的用戶重定向到所請求的安全資源。

          5. 對不具備訪問安全資源特權(quán)的用戶顯示 Access Denied 頁面。

          6. 在服務(wù)器上記錄成功進(jìn)行身份驗(yàn)證的用戶,并在用戶的客戶機(jī)上設(shè)置安全 cookie。使用該 cookie 執(zhí)行下一次身份驗(yàn)證,而無需要求用戶登錄。

          7. 將身份驗(yàn)證信息存儲(chǔ)在服務(wù)器端的會(huì)話對象中,從而安全地進(jìn)行對資源的后續(xù)請求。

          8. 在服務(wù)器端對象中構(gòu)建并保存安全信息的緩存,從而優(yōu)化性能。

          9. 當(dāng)用戶退出時(shí),刪除為用戶安全會(huì)話而保存的服務(wù)器端對象。

          10. 與大量后端數(shù)據(jù)存儲(chǔ)服務(wù)(如目錄服務(wù)或關(guān)系數(shù)據(jù)庫)進(jìn)行通信,這些服務(wù)用于存儲(chǔ)用戶的安全信息和 ECM 的訪問控制策略。

          正如這個(gè)列表顯示的那樣,Acegi 的安全過濾器允許您執(zhí)行保護(hù)企業(yè)應(yīng)用程序所需的幾乎任何事情。





          回頁首


          架構(gòu)和組件

          對 Acegi 了解越多,使用起來就越簡單。這一節(jié)介紹 Acegi 的組件;接下來您將了解該框架如何使用反轉(zhuǎn)控制(IOC)和 XML 配置文件來組合組件并表示它們的依賴關(guān)系。

          四大組件

          Acegi Security System 由四種主要類型的組件組成:過濾器、管理器、提供者和處理程序。

          過濾器
          這種最高級(jí)的組件提供了常見的安全服務(wù),如身份驗(yàn)證、會(huì)話處理以及注銷。我將在 本文后面的部分 深入討論過濾器。
          管理器
          過濾器僅是安全相關(guān)功能的高級(jí)抽象:實(shí)際上要使用管理器和提供者實(shí)現(xiàn)身份驗(yàn)證處理和注銷服務(wù)。管理器管理由不同提供者提供的較低級(jí)的安全服務(wù)。
          提供者
          有大量的提供者可用于和不同類型的數(shù)據(jù)存儲(chǔ)服務(wù)通信,例如目錄服務(wù)、關(guān)系數(shù)據(jù)庫或簡單的內(nèi)存中的對象。這意味著您可以將用戶庫和訪問控制協(xié)議存儲(chǔ)在任何一種這樣的數(shù)據(jù)存儲(chǔ)服務(wù)中,并且 Acegi 的管理器將在運(yùn)行時(shí)選擇合適的提供者。
          處理程序
          有時(shí)任務(wù)可能會(huì)被分解為多個(gè)步驟,其中每個(gè)步驟由一個(gè)特定的處理程序執(zhí)行。比方說,Acegi 的 注銷過濾器 使用兩個(gè)處理程序來退出一個(gè) HTTP 客戶機(jī)。其中一個(gè)處理程序使用戶的 HTTP 會(huì)話無效,而另一個(gè)處理程序則刪除用戶的 cookie。當(dāng)根據(jù)應(yīng)用程序需求配置 Acegi 時(shí),多個(gè)處理程序能夠提供很好的靈活性。您可以使用自己選擇的處理程序來執(zhí)行保護(hù)應(yīng)用程序所需的步驟。

          反轉(zhuǎn)控制

          Acegi 的組件通過彼此之間的依賴來對企業(yè)應(yīng)用程序進(jìn)行保護(hù)。比如,一個(gè)身份驗(yàn)證處理過濾器需要一個(gè)身份驗(yàn)證管理器選擇一個(gè)合適的身份驗(yàn)證提供者。這就是說您必須能夠表示和管理 Acegi 組件的依賴關(guān)系。

          IOC 實(shí)現(xiàn)通常用于管理 Java 組件之間的依賴關(guān)系。IOC 提供了兩個(gè)重要的特性:

          1. 它提供了一種語法,表示應(yīng)用程序所需的組件以及這些組件如何相互依賴。

          2. 它保證了所需的組件在運(yùn)行時(shí)是可用的。

          XML 配置文件

          Acegi 使用 Spring 框架(請參見 參考資料)附帶的流行開源 IOC 實(shí)現(xiàn)來管理其組件。Spring 需要您編寫一個(gè) XML 配置文件來表示組件的依賴關(guān)系,如清單 1 所示:


          清單 1. Spring 配置文件的結(jié)構(gòu)
                                  <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> 標(biāo)記,它封裝了一些其他的 <bean> 標(biāo)記。所有的 Acegi 組件(即過濾器、管理器、提供者等)實(shí)際上都是 JavaBean。XML 配置文件中的每個(gè) <bean> 標(biāo)記都代表一個(gè) Acegi 組件。

          進(jìn)一步解釋 XML 配置文件

          首先將注意到的是每個(gè) <bean> 標(biāo)記都包含一個(gè) class 屬性,這個(gè)屬性標(biāo)識(shí)組件所使用的類。<bean> 標(biāo)記還具有一個(gè) id 屬性,它標(biāo)識(shí)作為 Acegi 組件工作的實(shí)例(Java 對象)。

          比方說,清單 1 的第一個(gè) <bean> 標(biāo)記標(biāo)識(shí)了名為 filterChainProxy 的組件實(shí)例,它是名為 org.acegisecurity.util.FilterChainProxy 的類的實(shí)例。

          使用 <bean> 標(biāo)記的子標(biāo)記來表示 bean 的依賴關(guān)系。比如,注意第一個(gè) <bean> 標(biāo)記的 <property> 子標(biāo)記。<property> 子標(biāo)記定義了 <bean> 標(biāo)記依賴的其他 bean 或值。

          所以在 清單 1 中,第一個(gè) <bean> 標(biāo)記的 <property> 子標(biāo)記具有一個(gè) name 屬性和一個(gè) <value> 子標(biāo)記,分別定義了這個(gè) bean 依賴的屬性的名稱和值。

          同樣,清單 1 中的第二個(gè)和第三個(gè) <bean> 標(biāo)記定義了一個(gè)過濾器 bean 依賴于一個(gè)管理器 bean。第二個(gè) <bean> 標(biāo)記表示過濾器 bean,而第三個(gè) <bean> 標(biāo)記表示管理器 bean。

          過濾器的 <bean> 標(biāo)記包含一個(gè) <property> 子標(biāo)記,該子標(biāo)記具有兩個(gè)屬性:namerefname 屬性定義了過濾器 bean 的屬性,而 ref 屬性引用了管理器 bean 的實(shí)例(名稱)。

          下一節(jié)將展示如何在 XML 配置文件中配置 Acegi 過濾器。在本文后面的內(nèi)容中,您將在一個(gè)樣例 Acegi 應(yīng)用程序中使用過濾器。





          回頁首


          安全過濾器

          正如我前面提到的一樣,Acegi 使用安全過濾器為企業(yè)應(yīng)用程序提供身份驗(yàn)證和授權(quán)服務(wù)。您可以根據(jù)應(yīng)用程序的需要使用和配置不同類型的過濾器。這一節(jié)將介紹五種最重要的 Acegi 安全過濾器。

          Session Integration Filter

          Acegi 的 Session Integration Filter(SIF)通常是您將要配置的第一個(gè)過濾器。SIF 創(chuàng)建了一個(gè)安全上下文對象,這是一個(gè)與安全相關(guān)的信息的占位符。其他 Acegi 過濾器將安全信息保存在安全上下文中,也會(huì)使用安全上下文中可用的安全信息。

          SIF 創(chuàng)建安全上下文并調(diào)用過濾器鏈中的其他過濾器。然后其他過濾器檢索安全上下文并對其進(jìn)行更改。比如,Authentication Processing Filter(我將稍后進(jìn)行介紹)將用戶信息(如用戶名、密碼和電子郵件地址)存儲(chǔ)在安全上下文中。

          當(dāng)所有的處理程序完成處理后,SIF 檢查安全上下文是否更新。如果任何一個(gè)過濾器對安全上下文做出了更改,SIF 將把更改保存到服務(wù)器端的會(huì)話對象中。如果安全上下文中沒有發(fā)現(xiàn)任何更改,那么 SIF 將刪除它。

          在 XML 配置文件中對 SIF 進(jìn)行了配置,如清單 2 所示:


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

          Authentication Processing Filter

          Acegi 使用 Authentication Processing Filter(APF)進(jìn)行身份驗(yàn)證。APF 使用一個(gè)身份驗(yàn)證(或登錄)表單,用戶在其中輸入用戶名和密碼,并觸發(fā)身份驗(yàn)證。

          APF 執(zhí)行所有的后端身份驗(yàn)證處理任務(wù),比如從客戶機(jī)請求中提取用戶名和密碼,從后端用戶庫中讀取用戶參數(shù),以及使用這些信息對用戶進(jìn)行身份驗(yàn)證。

          在配置 APF 時(shí),您必須提供如下參數(shù):

          • Authentication manager 指定了用來管理身份驗(yàn)證提供者的身份驗(yàn)證管理器。

          • Filter processes URL 指定了客戶在登錄窗口中按下 Sign In 按鈕時(shí)要訪問的 URL。收到這個(gè) URL 的請求后,Acegi 立即調(diào)用 APF。

          • Default target URL 指定了成功進(jìn)行身份驗(yàn)證和授權(quán)后呈現(xiàn)給用戶的頁面。

          • Authentication failure URL 指定了身份驗(yàn)證失敗情況下用戶看到的頁面。

          APF 從用戶的請求對象中得到用戶名、密碼和其他信息。它將這些信息傳送給身份驗(yàn)證管理器。身份驗(yàn)證管理器使用適當(dāng)?shù)奶峁┱邚暮蠖擞脩魩熘凶x取詳細(xì)的用戶信息(如用戶名、密碼、電子郵件地址和用戶訪問權(quán)利或特權(quán)),對用戶進(jìn)行身份驗(yàn)證,并將信息存儲(chǔ)在一個(gè) Authentication 對象中。

          最后,APF 將 Authentication 對象保存在 SIF 之前創(chuàng)建的安全上下文中。存儲(chǔ)在安全上下文中的 Authentication 對象將用于做出授權(quán)決策。

          APF 的配置如清單 3 所示:


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

          可以從這段代碼中看到,APF 依賴于上面討論的這四個(gè)參數(shù)。每個(gè)參數(shù)都是作為清單 3 所示的 <property> 標(biāo)記配置的。

          Logout Processing Filter

          Acegi 使用一個(gè) Logout Processing Filer(LPF)管理注銷處理。當(dāng)客戶機(jī)發(fā)來注銷請求時(shí),將使用 LPF 進(jìn)行處理。它標(biāo)識(shí)了來自由客戶機(jī)所調(diào)用 URL 的注銷請求。

          LPF 的配置如清單 4 所示:


          清單 4. 配置 LPF
                                  <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
                      <constructor-arg value="/logoutSuccess.jsp"/>
                      <constructor-arg>
                      <list>
                      <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
                      </list>
                      </constructor-arg>
                      </bean>
                      

          可以看到 LPF 在其構(gòu)造方法中包含兩個(gè)參數(shù):注銷成功 URL(/logoutSuccess.jsp)和處理程序列表。注銷成功 URL 用來在注銷過程完成后重定向客戶機(jī)。處理程序執(zhí)行實(shí)際的注銷過程;我在這里只配置了一個(gè)處理程序,因?yàn)橹恍枰粋€(gè)處理程序就可以使 HTTP 會(huì)話變?yōu)闊o效。我將在本系列下一篇文章中討論更多的處理程序。

          Exception Translation Filter

          Exception Translation Filter(ETF)處理身份驗(yàn)證和授權(quán)過程中的異常情況,比如授權(quán)失敗。在這些異常情況中,ETF 將決定如何進(jìn)行操作。

          比如,如果一個(gè)沒有進(jìn)行身份驗(yàn)證的用戶試圖訪問受保護(hù)的資源,ETF 將顯示一個(gè)登錄頁面要求用戶進(jìn)行身份驗(yàn)證。類似地,在授權(quán)失敗的情況下,可以配置 ETF 來呈現(xiàn)一個(gè) Access Denied 頁面。

          ETF 的配置如清單 5 所示:


          清單 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 所示,ETF 包含兩個(gè)參數(shù),名為 authenticationEntryPointaccessDeniedHandlerauthenticationEntryPoint 屬性指定登錄頁面,而 accessDeniedHandler 指定 Access Denied 頁面。

          攔截過濾器

          Acegi 的攔截過濾器 用于做出授權(quán)決策。您需要在 APF 成功執(zhí)行身份驗(yàn)證后對攔截過濾器進(jìn)行配置,以使其發(fā)揮作用。攔截器使用應(yīng)用程序的訪問控制策略來做出授權(quán)決定。

          本系列的下一篇文章將展示如何設(shè)計(jì)訪問控制策略,如何將它們托管在目錄服務(wù)中,以及如何配置 Acegi 以讀取您的訪問控制策略。但是,目前我將繼續(xù)向您展示如何使用 Acegi 配置一個(gè)簡單的訪問控制策略。在本文后面的部分,您將看到使用簡單的訪問控制策略構(gòu)建一個(gè)樣例應(yīng)用程序。

          配置簡單的訪問控制策略可分為兩個(gè)步驟:

          1. 編寫訪問控制策略。

          2. 根據(jù)策略配置 Acegi 的攔截過濾器。

          步驟 1. 編寫簡單的訪問控制策略

          首先看一下 清單 6,它展示了如何定義一個(gè)用戶及其用戶角色:


          清單 6. 為用戶定義簡單的訪問控制策略
                                  alice=123,ROLE_HEAD_OF_ENGINEERING
                      

          清單 6 所示的訪問控制策略定義了用戶名 alice,它的密碼是 123,角色是 ROLE_HEAD_OF_ENGINEERING。(下一節(jié)將說明如何在文件中定義任意數(shù)量的用戶及其用戶角色,然后配置攔截過濾器以使用這些文件。)

          步驟 2. 配置 Acegi 的攔截過濾器

          攔截過濾器使用三個(gè)組件來做出授權(quán)決策,我在清單 7 中對其進(jìn)行了配置:


          清單 7. 配置攔截過濾器
                                  <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 所示,配置所需的三個(gè)組件是 authenticationManageraccessDecisionManagerobjectDefinitionSource

          • authenticationManager 組件與我在介紹 Authentication Processing Filter 時(shí)討論過的身份驗(yàn)證管理器相同。攔截過濾器可以在授權(quán)的過程中使用 authenticationManager 重新對客戶機(jī)進(jìn)行身份驗(yàn)證。

          • accessDecisionManager 組件管理授權(quán)過程,這部分內(nèi)容將在本系列的下篇文章中詳細(xì)討論。

          • objectDefinitionSource 組件包含對應(yīng)于將要發(fā)生的授權(quán)的訪問控制定義。例如,清單 7 中的 objectDefinitionSource 屬性值包含兩個(gè) URL(/protected/*/*)。其值定義了這些 URL 的角色。/protected/* URL 的角色是 ROLE_HEAD_OF_ENGINEERING。您可以根據(jù)應(yīng)用程序的需要定義任何角色。

            回想一下 清單 6,您為用戶名 alice 定義了 ROLE_HEAD_OF_ENGINEERING。這就是說 alice 將能夠訪問 /protected/* URL。




          回頁首


          過濾器工作原理

          正如您已經(jīng)了解到的一樣,Acegi 的組件彼此依賴,從而對您的應(yīng)用程序進(jìn)行保護(hù)。在本文后面的部分,您將看到如何對 Acegi 進(jìn)行配置,從而按照特定的順序應(yīng)用安全過濾器,因此需要?jiǎng)?chuàng)建過濾器鏈。出于這個(gè)目的,Acegi 保存了一個(gè)過濾器鏈對象,它封裝了為保護(hù)應(yīng)用程序而配置了的所有過濾器。圖 1 展示了 Acegi 過濾器鏈的生命周期,該周期從客戶機(jī)向您的應(yīng)用程序發(fā)送 HTTP 請求開始。(圖 1 顯示了服務(wù)于瀏覽器客戶機(jī)的容器。)


          圖 1. 托管 Acegi 過濾器鏈以安全地為瀏覽器客戶機(jī)服務(wù)的容器
          Acegi 過濾器的生命周期

          下面的步驟描述了過濾器鏈的生命周期:

          1. 瀏覽器客戶機(jī)向您的應(yīng)用程序發(fā)送 HTTP 請求。

          2. 容器接收到 HTTP 請求并創(chuàng)建一個(gè)請求對象,該對象將封裝 HTTP 請求中包含的信息。容器還創(chuàng)建一個(gè)各種過濾器都可處理的響應(yīng)對象,從而為發(fā)出請求的客戶機(jī)準(zhǔn)備好 HTTP 響應(yīng)。容器然后調(diào)用 Acegi 的過濾器鏈代理,這是一個(gè)代理過濾器。該代理知道應(yīng)用的過濾器的實(shí)際順序。當(dāng)容器調(diào)用代理時(shí),它將向代理發(fā)送請求、響應(yīng)以及過濾器鏈對象。

          3. 代理過濾器調(diào)用過濾器鏈中第一個(gè)過濾器,向其發(fā)送請求、響應(yīng)和過濾器鏈對象。

          4. 鏈中的過濾器逐個(gè)執(zhí)行其處理。一個(gè)過濾器可以通過調(diào)用過濾器鏈中下一個(gè)過濾器隨時(shí)終止自身處理。有的過濾器甚至根本不執(zhí)行任何處理(比如,如果 APF 發(fā)現(xiàn)一個(gè)到來的請求沒有要求身份驗(yàn)證,它可能會(huì)立即終止其處理)。

          5. 當(dāng)身份驗(yàn)證過濾器完成其處理時(shí),這些過濾器將把請求和響應(yīng)對象發(fā)送到應(yīng)用程序中配置的攔截過濾器。

          6. 攔截器決定是否對發(fā)出請求的客戶機(jī)進(jìn)行授權(quán),使它訪問所請求的資源。

          7. 攔截器將控制權(quán)傳輸給應(yīng)用程序(比如,成功進(jìn)行了身份驗(yàn)證和授權(quán)的客戶機(jī)請求的 JSP 頁面)。

          8. 應(yīng)用程序改寫響應(yīng)對象的內(nèi)容。

          9. 響應(yīng)對象已經(jīng)準(zhǔn)備好了,容器將響應(yīng)對象轉(zhuǎn)換為 HTTP 響應(yīng),并將響應(yīng)發(fā)送到發(fā)出請求的客戶機(jī)。

          為幫助您進(jìn)一步理解 Acegi 過濾器,我將詳細(xì)探討其中兩個(gè)過濾器的操作:Session Integration Filter 和 Authentication Processing Filter。

          SIF 如何創(chuàng)建一個(gè)安全上下文

          圖 2 展示了 SIF 創(chuàng)建安全上下文所涉及到的步驟:


          圖 2. SIF 創(chuàng)建安全上下文
          SIF 如何創(chuàng)建安全上下文

          現(xiàn)在詳細(xì)地考慮下面這些步驟:

          1. Acegi 的過濾器鏈代理調(diào)用 SIF 并向其發(fā)送請求、響應(yīng)和過濾器鏈對象。注意:通常將 SIF 配置為過濾器鏈中第一個(gè)過濾器。

          2. SIF 檢查它是否已經(jīng)對這個(gè) Web 請求進(jìn)行過處理。如果是的話,它將不再進(jìn)一步進(jìn)行處理,并將控制權(quán)傳輸給過濾器鏈中的下一個(gè)過濾器(參見下面的第 4 個(gè)步驟)。如果 SIF 發(fā)現(xiàn)這是第一次對這個(gè) Web 請求調(diào)用 SIF,它將設(shè)置一個(gè)標(biāo)記,將在下一次使用該標(biāo)記,以表示曾經(jīng)調(diào)用過 SIF。

          3. SIF 將檢查是否存在一個(gè)會(huì)話對象,以及它是否包含安全上下文。它從會(huì)話對象中檢索安全上下文,并將其放置在名為 security context holder 的臨時(shí)占位符中。如果不存在會(huì)話對象,SIF 將創(chuàng)建一個(gè)新的安全上下文,并將它放到 security context holder 中。注意:security context holder 位于應(yīng)用程序的范圍內(nèi),所以可以被其他的安全過濾器訪問。

          4. SIF 調(diào)用過濾器鏈中的下一個(gè)過濾器。

          5. 其他過濾器可以編輯安全上下文。

          6. SIF 在過濾器鏈完成處理后接收控制權(quán)。

          7. SIF 檢查其他的過濾器是否在其處理過程中更改了安全上下文(比如,APF 可能將用戶詳細(xì)信息存儲(chǔ)在安全上下文中)。如果是的話,它將更新會(huì)話對象中的安全上下文。就是說在過濾器鏈處理過程中,對安全上下文的任何更改現(xiàn)在都保存在會(huì)話對象中。

          APF 如何對用戶進(jìn)行身份驗(yàn)證

          圖 3 展示了 APF 對用戶進(jìn)行身份驗(yàn)證所涉及到的步驟:


          圖 3. APF 對用戶進(jìn)行身份驗(yàn)證
          APF 如何對用戶進(jìn)行身份驗(yàn)證

          現(xiàn)在仔細(xì)考慮以下這些步驟:

          1. 過濾器鏈中前面的過濾器向 APF 發(fā)送請求、響應(yīng)和過濾鏈對象。

          2. APF 使用從請求對象中獲得的用戶名、密碼以及其他信息創(chuàng)建身份驗(yàn)證標(biāo)記。

          3. APF 將身份驗(yàn)證標(biāo)記傳遞給身份驗(yàn)證管理器。

          4. 身份驗(yàn)證管理器可能包含一個(gè)或更多身份驗(yàn)證提供者。每個(gè)提供者恰好支持一種類型的身份驗(yàn)證。管理器檢查哪一種提供者支持它從 APF 收到的身份驗(yàn)證標(biāo)記。

          5. 身份驗(yàn)證管理器將身份驗(yàn)證標(biāo)記發(fā)送到適合進(jìn)行身份驗(yàn)證的提供者。

          6. 身份驗(yàn)證提供者支持從身份驗(yàn)證標(biāo)記中提取用戶名,并將它發(fā)送給名為 user cache service 的服務(wù)。Acegi 緩存了已經(jīng)進(jìn)行過身份驗(yàn)證的用戶。該用戶下次登錄時(shí),Acegi 可以從緩存中加載他或她的詳細(xì)信息(比如用戶名、密碼和權(quán)限),而不是從后端數(shù)據(jù)存儲(chǔ)中讀取數(shù)據(jù)。這種方法使得性能得到了改善。

          7. user cache service 檢查用戶的詳細(xì)信息是否存在于緩存中。

          8. user cache service 將用戶的詳細(xì)信息返回給身份驗(yàn)證提供者。如果緩存不包含用戶詳細(xì)信息,則返回 null。

          9. 身份驗(yàn)證提供者檢查緩存服務(wù)返回的是用戶的詳細(xì)信息還是 null。

          10. 如果緩存返回 null,身份驗(yàn)證提供者將用戶名(在步驟 6 中提取)發(fā)送給另一個(gè)名為 user details service 的服務(wù)。

          11. user details service 與包含用戶詳細(xì)信息的后端數(shù)據(jù)存儲(chǔ)通信(如目錄服務(wù))。

          12. user details service 返回用戶的詳細(xì)信息,或者,如果找不到用戶詳細(xì)信息則拋出身份驗(yàn)證異常。

          13. 如果 user cache service 或者 user details service 返回有效的用戶詳細(xì)信息,身份驗(yàn)證提供者將使用 user cache service 或 user details service 返回的密碼來匹配用戶提供的安全標(biāo)記(如密碼)。如果找到一個(gè)匹配,身份驗(yàn)證提供者將用戶的詳細(xì)信息返回給身份驗(yàn)證管理器。否則的話,則拋出一個(gè)身份驗(yàn)證異常。

          14. 身份驗(yàn)證管理器將用戶的詳細(xì)信息返回給 APF。這樣用戶就成功地進(jìn)行了身份驗(yàn)證。

          15. APF 將用戶詳細(xì)信息保存在 圖 2 所示由步驟 3 創(chuàng)建的安全上下文中。

          16. APF 將控制權(quán)傳輸給過濾器鏈中的下一個(gè)過濾器。




          回頁首


          一個(gè)簡單的 Acegi 應(yīng)用程序

          在本文中,您已經(jīng)了解了很多關(guān)于 Acegi 的知識(shí),所以現(xiàn)在看一下利用您目前學(xué)到的知識(shí)能做些什么,從而結(jié)束本文。對于這個(gè)簡單的演示,我設(shè)計(jì)了一個(gè)樣例應(yīng)用程序(參見 下載),并對 Acegi 進(jìn)行了配置以保護(hù)它的一些資源。

          樣例應(yīng)用程序包含 5 個(gè) JSP 頁面:index.jsp、protected1.jsp、protected2.jsp、login.jsp 和 accessDenied.jsp。

          index.jsp 是應(yīng)用程序的歡迎頁面。它向用戶顯示了三個(gè)超鏈接,如圖 4 所示:


          圖 4. 樣例應(yīng)用程序的歡迎頁面:
          一個(gè)簡單的 Acegi 應(yīng)用程序

          圖 4 所示的鏈接中,其中兩個(gè)鏈接指向了被保護(hù)的資源(protected1.jsp 和 protected2.jsp),第三個(gè)鏈接指向登錄頁面(login.jsp)。只有在 Acegi 發(fā)現(xiàn)用戶沒有被授權(quán)訪問受保護(hù)的資源時(shí),才會(huì)顯示 accessDenied.jsp 頁面。

          如果用戶試圖訪問任何受保護(hù)的頁面,樣例應(yīng)用程序?qū)@示登錄頁面。當(dāng)用戶使用登錄頁面進(jìn)入后,應(yīng)用程序?qū)⒆詣?dòng)重定向到被請求的受保護(hù)資源。

          用戶可以通過單擊歡迎頁面中的第三個(gè)鏈接直接請求登錄頁面。這種情況下,應(yīng)用程序顯示用戶可以進(jìn)入系統(tǒng)的登錄頁面。進(jìn)入系統(tǒng)以后,應(yīng)用程序?qū)⒂脩糁囟ㄏ虻?protected1.jsp,它是用戶進(jìn)入系統(tǒng)而沒有請求特定的受保護(hù)資源時(shí)顯示的默認(rèn)資源。

          配置樣例應(yīng)用程序

          為本文下載的源代碼包含一個(gè)名為 acegi-config.xml 的 XML 配置文件,它包含 Acegi 過濾器的配置。根據(jù) 安全過濾器的討論 中的示例,您應(yīng)該很熟悉這些配置。

          我還為樣例應(yīng)用程序編寫了一個(gè) web.xml 文件,如清單 8 所示:


          清單 8. 樣例應(yīng)用程序的 web.xml 文件
                                  <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 文件配置如下:

          • acegi-config.xml 文件的 URL 位于 <context-param> 標(biāo)記中。

          • Acegi 過濾器鏈代理類的名稱位于 <filter> 標(biāo)記中。

          • URL 到 Acegi 過濾器鏈代理的映射在 <filter-mapping> 標(biāo)記中。注意:您可以簡單地將應(yīng)用程序的所有 URL(/*)映射到 Acegi 過濾器鏈代理。Acegi 將對映射到 Acegi 過濾器鏈代理上的所有 URL 應(yīng)用安全性。

          • 應(yīng)用程序上下文加載程序位于 <listener> 標(biāo)記中,它將加載 Spring 的 IOC 框架。

          部署并運(yùn)行應(yīng)用程序

          部署并運(yùn)行樣例應(yīng)用程序非常的簡單。只需要完成兩件事情:

          1. 將 acegisample.war 文件從本教程下載的源代碼中復(fù)制到安裝 Tomcat 的 webapps 目錄中。

          2. 從 Acegi Security System 主頁 下載并解壓縮 acegi-security-1.0.3.zip。您將找到一個(gè)名為 acegi-security-sample-tutorial.war 的樣例應(yīng)用程序。解壓縮 war 文件并提取其 WEB-INF/lib 文件夾中所有的 jar 文件。將所有的 JAR 文件從 WEB-INF/lib 文件夾中復(fù)制到 theacegisample.war 應(yīng)用程序的 WEB-INF/lib 文件夾。

          現(xiàn)在,您已經(jīng)為運(yùn)行樣例應(yīng)用程序做好準(zhǔn)備了。啟動(dòng) Tomcat 并將瀏覽器指向 http://localhost:8080/acegisample/

          您將看到 圖 4 所示的歡迎頁面,但是此時(shí)顯示的頁面是真實(shí)的。請繼續(xù)運(yùn)行程序,并查看在嘗試訪問歡迎頁面顯示的不同鏈接時(shí)會(huì)發(fā)生什么狀況。





          回頁首


          結(jié)束語

          使用 Acegi 保護(hù) Java 應(yīng)用程序 系列的第一篇文章中,您了解了 Acegi 安全系統(tǒng)的特性、架構(gòu)和組件,學(xué)習(xí)了大量有關(guān) Acegi 安全過濾器的知識(shí),這些過濾器被集成到 Acegi 的安全框架中。您還學(xué)習(xí)了如何使用 XML 配置文件配置組件依賴關(guān)系,并查看了 Acegi 的安全過濾器在樣例程序中工作的情形,該應(yīng)用程序可以實(shí)現(xiàn)基于 URL 的安全性。

          本文所述的安全技術(shù)非常的簡單,所以 Acegi 使用這些技術(shù)實(shí)現(xiàn)安全性。本系列的下一文章將開始介紹 Acegi 的一些較為高級(jí)的應(yīng)用,首先是編寫訪問控制協(xié)議并將其存儲(chǔ)到目錄服務(wù)中。您還將了解到如何配置 Acegi,使它與目錄服務(wù)交互,從而實(shí)現(xiàn)您的訪問控制策略。






          回頁首


          下載

          描述 名字 大小 下載方法
          本文源代碼 j-acegi1.zip 10KB HTTP
          關(guān)于下載方法的信息


          參考資料

          學(xué)習(xí)

          獲得產(chǎn)品和技術(shù)

          討論


          關(guān)于作者

           

          Bilal Siddiqui 是一名電子工程師、XML 顧問,他還是 WaxSys(主要從事電子商務(wù)簡化)的創(chuàng)建者之一。自從 1995 年畢業(yè)于拉合爾工程技術(shù)大學(xué)(University of Engineering and Technology,Lahore)電子工程專業(yè)以后,他就開始為工業(yè)控制系統(tǒng)設(shè)計(jì)各種軟件解決方案。稍后,他致力于 XML 方面并使用他在 C++ 編程中取得的經(jīng)驗(yàn)來構(gòu)建基于 Web 和 WAP 的 XML 處理工具、服務(wù)器端解析方案和服務(wù)應(yīng)用程序。Bilal 是一名技術(shù)推廣者,并且是一名多產(chǎn)的技術(shù)作家。



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

          posted @ 2008-05-08 18:41 狼愛上貍 閱讀(362) | 評(píng)論 (0)編輯 收藏

          實(shí)戰(zhàn)Acegi:使用Acegi作為基于Spring框架的WEB應(yīng)用的安全框架

          最近項(xiàng)目使用Acegi作為安全框架的實(shí)現(xiàn),效果不錯(cuò),就寫了這篇文章作為總結(jié).

          對于任何一個(gè)完整的應(yīng)用系統(tǒng),完善的認(rèn)證和授權(quán)機(jī)制是必不可少的。在基于SpringFramework的WEB應(yīng)用中,
          我們可以使用Acegi作為安全架構(gòu)的實(shí)現(xiàn)。本文將介紹如何在基于Spring構(gòu)架的Web應(yīng)用中使用Acegi,并且詳細(xì)介
          紹如何配置和擴(kuò)展Acegi框架以適應(yīng)實(shí)際需要。

          文章和代碼下載:

          http://www.aygfsteel.com/Files/youlq/Acegi.zip


          注意:許多朋友在部署上遇到一些麻煩,所以我將可以部署的完整的war文件傳上來,注意:java代碼在acegi-sample.war\WEB-INF 目錄下,例子需要Mysql,建庫腳本在acegi-sample.war\db目錄下。

          acegi-sample.part1.rar
          acegi-sample.part2.rar
          acegi-sample.part3.rar
          acegi-sample.part4.rar

          附注:

          有些朋友詢問我如何部署文中的例子,在此再次說明一下(文章中已經(jīng)有提到):

          Mysql的建表腳本在db目錄下
          為了減小體積,已經(jīng)將WEB-INF\lib下的依賴包刪除,請自行下載以下包,并拷貝至WEB-INF\lib下:
          spring-1.2.4.jar
          acegi-security-0.8.3.jar
          aopalliance-1.0.jar
          c3p0-0.9.0.jar
          commons-logging-1.0.4.jar
          ehcache-1.1.jar
          log4j-1.2.8.jar
          mysql-connector-java-3.1.10-bin.jar
          oro-2.0.8.jar

          提示:
          acegi-security-0.8.3.jar
          aopalliance-1.0.jar
          c3p0-0.9.0.jar
          commons-logging-1.0.4.jar
          ehcache-1.1.jar
          log4j-1.2.8.jar
          oro-2.0.8.jar
          可以在acegi-security-0.8.3.zip所帶的acegi-security-sample-contacts-filter.war中找到。
          spring-1.2.4.jar
          mysql-connector-java-3.1.10-bin.jar
          要分別到springframework和mysql網(wǎng)站下載。


          來自:http://www.aygfsteel.com/youlq/archive/2005/12/06/22678.html

          posted @ 2008-05-08 18:37 狼愛上貍 閱讀(689) | 評(píng)論 (0)編輯 收藏

          Acegi的下載和安裝

          1  Acegi官方發(fā)布版的下載和安裝

          開發(fā)者可以通過http://sourceforge.net/projects/acegisecurity或http://acegisecurity.org/下載到Acegi官方發(fā)布版,比如acegi-security-1.x.zip。圖4-4展示了SF中Acegi項(xiàng)目的首頁,它提供了下載Acegi(Spring Security)的入口。

          圖4-4  http://sourceforge.net/projects/acegisecurity首頁

          在單擊圖4-4中的下載(“Download Acegi Security System for Spring”)超鏈接后,開發(fā)者進(jìn)而能夠下載到最新的Acegi官方發(fā)布包。此時(shí),建議開發(fā)者同時(shí)將acegi-security-1.x.zip、acegi-security-1.x-src.zip下載到本地,前者包含了Jar存檔和若干Acegi使能應(yīng)用,而后者僅僅包含了Acegi項(xiàng)目的源代碼。

          在下載到Acegi官方發(fā)布版后,通過解壓acegi-security-1.x.zip,開發(fā)者能夠?yàn)g覽到如圖4-5所示的類似內(nèi)容。

          圖4-5  acegi-security-1.x.zip包含的內(nèi)容

          通常,大部分Acegi安全性項(xiàng)目僅僅需要使用到acegi-security-1.x.jar存檔,這是Acegi的核心包,任何Acegi使能項(xiàng)目都需要使用到它。如果項(xiàng)目打算采用Java SE 5引入的Annotation注釋支持,則還需要將acegi-security-tiger-1.x.jar添加到WEB-INF/lib中。如果開發(fā)者在使用Acegi提供的容器適配器支持,則還需要將acegi-security-catalina-1.x.jar(針對Tomcat)、acegi-security-jboss-1.x.jar(針對JBoss)、acegi-security-jetty-1.x.jar(針對Jetty)、acegi-security-resin-1.x.jar(針對Resin)等Jar存檔復(fù)制到相應(yīng)的位置,至于這些Jar包的具體使用,本書將在第10章詳細(xì)闡述。

          另外,acegi-security-sample-contacts-filter.war、acegi-security-sample-tutorial.war是兩個(gè)直接可部署到Java EE容器(Tomcat容器)中的Web應(yīng)用。

          2  Subversion中的Acegi源碼下載和安裝

          如今,Acegi基代碼采用Subversion管理。開發(fā)者通過如圖4-6所示的Web頁面能夠獲得Subversion下載地址(http://sourceforge.net/svn/?group_id=104215)。

          圖4-6  獲得下載Acegi基代碼地址的Web頁面

          事實(shí)上,Acegi(Spring Security)基代碼本身就是一個(gè)Eclipse Java項(xiàng)目,而且它的構(gòu)建、管理工作采用了Maven 1.x/2.x(http://maven.apache.org/)。開發(fā)者可以借助Eclipse Subversive插件從Subversion存儲(chǔ)源獲得Acegi的最新基代碼。圖4-7展示了Subversive內(nèi)置的SVN Repository Exploring。

          圖4-7  Subversive插件使用截圖

          一旦在下載完成Acegi(Spring Security)基代碼后,開發(fā)者將能夠持續(xù)監(jiān)控到Acegi項(xiàng)目的最新情況,比如獲得Acegi持續(xù)更新的基代碼、Acegi官方文檔,圖4-8展示了相應(yīng)的使用截圖。

          圖4-8  持續(xù)更新Acegi基代碼

          3  有關(guān)Acegi的權(quán)威去處

          其一,開發(fā)者可以去訂閱acegisecurity-developer@lists.sourceforge.net郵件列表,圖4-9展示了訂閱這一郵件列表的入口。Acegi開發(fā)團(tuán)隊(duì)積極參與到這一郵件列表中,因此開發(fā)者從這一郵件列表能夠獲得Acegi的最新進(jìn)展。

          圖4-9  訂閱Acegi開發(fā)者郵件列表

          其二,Acegi官方論壇(http://forum.springframework.org/),圖4-10展示了論壇截圖。

          圖4-10  Acegi官方論壇

          開發(fā)者可以通過許多渠道獲得一手的Acegi知識(shí)、開發(fā)和部署經(jīng)驗(yàn)。

          5  小結(jié)

          本章圍繞Acegi(Spring Security)的認(rèn)證策略進(jìn)行了闡述,比如基于過濾器的設(shè)計(jì)、與認(rèn)證源解耦、AcegiSecurityException異常體系等。另外,我們還針對Acegi發(fā)布版和基代碼的下載進(jìn)行了簡要介紹。

          下章將深入到Acegi支持的各種認(rèn)證機(jī)制中。

          【參考及推薦資料】

          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

          posted @ 2008-05-08 18:35 狼愛上貍 閱讀(1853) | 評(píng)論 (0)編輯 收藏

          讓不同系統(tǒng)內(nèi)容共享:IBM內(nèi)容管理系統(tǒng)方案

                 如何實(shí)施內(nèi)容管理解決方案呢?讓我們借鑒一下如下做法。

            IBM內(nèi)容管理第8版(CM V8)提供了一套可靠的、易升級(jí)的、強(qiáng)勁的企業(yè)內(nèi)容管理體系架構(gòu),它也同時(shí)提供了強(qiáng)勁的、安全的和高擴(kuò)展能力的服務(wù),使得企業(yè)用戶能非常容易地訪問電子商務(wù)的內(nèi)容。這種體系架構(gòu)能夠通過具有強(qiáng)勁、靈活的數(shù)據(jù)模型的單一存儲(chǔ)庫來支持不同的、異構(gòu)的內(nèi)容管理技術(shù),包括文檔管理、數(shù)字媒體資產(chǎn)管理、網(wǎng)站內(nèi)容管理等,這種數(shù)據(jù)模型使得我們能非常容易地在不同系統(tǒng)之間實(shí)現(xiàn)內(nèi)容共享,從而提高了業(yè)務(wù)處理流程效率。

            IBM CM V8也提供了各種特性來滿足對內(nèi)容整個(gè)生命周期的管理,包括捕獲、存儲(chǔ)、組織、流轉(zhuǎn)、歸檔、跟蹤和銷毀。

            IBM內(nèi)容管理解決方案平臺(tái)基于用戶對于內(nèi)容進(jìn)行管理的需求而開發(fā),并且IBM內(nèi)容管理產(chǎn)品第8版本有了更多的新功能。

          高擴(kuò)展性的體系架構(gòu)

            CM服務(wù)器由一個(gè)索引服務(wù)器(Library Server)、一個(gè)或多個(gè)對象服務(wù)器(Object Server或稱Resource Manager)和一個(gè)或多個(gè)客戶程序構(gòu)成,通過提供具有專利技術(shù)的三角形架構(gòu)的體系結(jié)構(gòu),使得系統(tǒng)能依據(jù)需求隨意擴(kuò)展。資源管理服務(wù)器能分布在網(wǎng)絡(luò)上的任何地方,并且通過統(tǒng)一的索引服務(wù)器而實(shí)現(xiàn)集中管理。它以堅(jiān)實(shí)的技術(shù)實(shí)力為基礎(chǔ),融合了基于SQL標(biāo)準(zhǔn)的關(guān)系數(shù)據(jù)庫。系統(tǒng)具有很強(qiáng)的擴(kuò)容性,可以由單機(jī)系統(tǒng)擴(kuò)容到SMP并行多處理器系統(tǒng)和SP超級(jí)并行處理計(jì)算機(jī)系統(tǒng)都可以適用。通過實(shí)現(xiàn)分布式基于對象的兩階段提交技術(shù),確保索引數(shù)據(jù)和媒體數(shù)據(jù)的參照完整性,從而不會(huì)出現(xiàn)孤島式的內(nèi)容對象。

          靈活、強(qiáng)勁的數(shù)據(jù)模型

            IBM CM V8提供了靈活、強(qiáng)勁的數(shù)據(jù)模型,通過CM V8的數(shù)據(jù)模型,能夠非常容易地實(shí)現(xiàn)任何復(fù)雜和多變的元數(shù)據(jù)標(biāo)準(zhǔn)。簡單來說,任何用XML格式描述的元數(shù)據(jù)信息,都可以在CM中得到快速實(shí)現(xiàn),并且靈活地進(jìn)行改變,從而充分和容易地通過客戶化來實(shí)現(xiàn)各種元數(shù)據(jù)標(biāo)準(zhǔn),而不需要任何系統(tǒng)設(shè)計(jì)和編程工作,且實(shí)現(xiàn)系統(tǒng)性能的最優(yōu)化。

          高效的查詢訪問能力

            CM提供了多種查詢方法,包括參數(shù)檢索、全文檢索以及面向中文的中文智能檢索,并且CM能支持用戶同時(shí)和分開使用這幾種檢索方法。

            通過參數(shù)檢索,用戶能快速訪問所有元數(shù)據(jù)信息,象客戶名稱、客戶號(hào)等。全文檢索能對已建立了文本索引的內(nèi)容進(jìn)行自由文本檢索,從而快速查找到相關(guān)的文檔;而中文智能檢索能力將基于中文語義進(jìn)行檢索,支持包括近義詞、上下位概念、同一名稱等智能檢索。

          企業(yè)范圍的內(nèi)容整合

            企業(yè)都有許多的信息孤島在管理著數(shù)據(jù)和數(shù)字內(nèi)容,這些解決方案都有它們自己的方式來訪問信息,包括語法、語義和接口都不一樣。定制的應(yīng)用開發(fā)需要從這些分離的數(shù)據(jù)源和專門的過濾方法來收集合訪問所有的信息。CM通過提供信息整合的體系架構(gòu)來實(shí)現(xiàn)單一入口的針對內(nèi)容存儲(chǔ)庫的訪問接口。

          分布式存儲(chǔ)和多級(jí)存儲(chǔ)管理

            CM的資源管理器是對象存儲(chǔ)庫,一個(gè)索引服務(wù)器能支持多個(gè)本地和遠(yuǎn)程的資源管理器,用戶通過索引服務(wù)器來對對象進(jìn)行存儲(chǔ)和訪問,資源管理器基于WebSphere的最新技術(shù)建立,通過標(biāo)準(zhǔn)的HTTP、FTP和FILE協(xié)議來進(jìn)行通訊,支持基于Internet的應(yīng)用。資源管理器和索引服務(wù)器合作來確保數(shù)據(jù)完整性和一致性,資源管理器通過數(shù)據(jù)庫來記錄對象的位置,同時(shí)資源管理器提供了緩存能力來提高對象訪問的性能。

          文檔流轉(zhuǎn)

            CM提供了易于使用的強(qiáng)勁的文檔流轉(zhuǎn)功能,能支持以內(nèi)容為基礎(chǔ)的業(yè)務(wù)流轉(zhuǎn),文檔流轉(zhuǎn)是CM內(nèi)置的工作流服務(wù),包含了很高的性能、很少的腳本、整合的權(quán)限控制列表以及強(qiáng)勁和靈活的工作流建模能力。文檔流轉(zhuǎn)功能在CM客戶端都得到了體現(xiàn),并且用戶可以非常容易地定制工作流應(yīng)用。用戶可以通過C++或Java,JavaBeans來實(shí)現(xiàn)工作流的操作和系統(tǒng)管理功能。

          更高級(jí)的工作流

            IBM CM提供了更高級(jí)的工作流功能,來實(shí)現(xiàn)企業(yè)范圍靈活的文檔流轉(zhuǎn)功能,EIP高級(jí)工作流支持并行流轉(zhuǎn)、數(shù)據(jù)變量和子進(jìn)程,并且提供了將CM、CM Ondemand、CM ImagePlus等存儲(chǔ)庫中的內(nèi)容進(jìn)行集中流轉(zhuǎn)的能力。

          高層次的應(yīng)用開發(fā)工具

            CM整個(gè)系統(tǒng)的設(shè)計(jì)完全圍繞著對象管理來進(jìn)行的,所以不管是數(shù)據(jù)模型,還是權(quán)限管理以及開發(fā)接口,我們都可以通過對象管理的方法DDO/XDO來進(jìn)行設(shè)置和開發(fā),而不需要面向SQL和底層的表結(jié)構(gòu)來進(jìn)行開發(fā),也不需要針對底層的存儲(chǔ)管理API來進(jìn)行開發(fā)。我們只需要通過統(tǒng)一的、滿足DDO/XDO標(biāo)準(zhǔn)的管理模式和API來進(jìn)行內(nèi)容管理,包括編目、權(quán)限、存儲(chǔ)、遷移、流程控制等等。

          開放標(biāo)準(zhǔn)的全面支持

            從Web環(huán)境、開發(fā)語言到網(wǎng)絡(luò)協(xié)議、操作系統(tǒng),乃至數(shù)據(jù)庫和應(yīng)用軟件,CM全部遵循通用的國際或行業(yè)標(biāo)準(zhǔn),如開發(fā)語言:C++、Java / Java Beans、ActiveX;傳輸連接標(biāo)準(zhǔn):XML、HTTP、RTSP、JDBC;格式標(biāo)準(zhǔn):TIFF等所有圖像格式、 HTML、Office、MPEG(1、2、4)、Quicktime、AVI、MP3等;協(xié)議標(biāo)準(zhǔn):CORBA、ODMA、LDAP、SQL和Xquery;系統(tǒng)平臺(tái):Sun Solaris、Windows、AIX、S/390、AS/400;其它數(shù)據(jù)源:Oracle、DB2、Microsft、Sybase和其它內(nèi)容管理系統(tǒng)。

          實(shí)施中的關(guān)鍵環(huán)節(jié)

            就目前一般的內(nèi)容管理應(yīng)用來看,應(yīng)該十分重視有效地采集、管理、應(yīng)用各種非結(jié)構(gòu)化和半結(jié)構(gòu)化的資源,并且將它們與企業(yè)的其他業(yè)務(wù)系統(tǒng)中的各種結(jié)構(gòu)化信息集成起來。

          成立專門小組實(shí)施內(nèi)容管理策略

            企業(yè)在制定內(nèi)容管理方案時(shí),應(yīng)考慮到設(shè)計(jì)、實(shí)施、質(zhì)量監(jiān)控的問題,人員的組成應(yīng)涉及到戰(zhàn)略、信息技術(shù)、業(yè)務(wù)等部門,同時(shí)還要有企業(yè)的主管領(lǐng)導(dǎo)參與,以使決策更加有效和迅速地執(zhí)行。 還要確立總體的項(xiàng)目計(jì)劃、實(shí)施策略、項(xiàng)目制度,以指導(dǎo)項(xiàng)目的進(jìn)行。

          梳理所有內(nèi)容

            在這個(gè)階段中,要對企業(yè)中現(xiàn)有的內(nèi)容資源進(jìn)行細(xì)致的盤清,確定企業(yè)內(nèi)容資源的價(jià)值、數(shù)量以及獲取這些內(nèi)容的難易程度。一般可以從三個(gè)方面著手:整理、清查已經(jīng)公開發(fā)布過的各種文檔;確定各種尚未公開發(fā)布過的各種知識(shí)資源;仔細(xì)地清點(diǎn)企業(yè)從外界得到的各種內(nèi)容資源,以此對企業(yè)內(nèi)部的內(nèi)容資產(chǎn)有一個(gè)全面的了解和把握,這是確定內(nèi)容管理系統(tǒng)內(nèi)容和技術(shù)架構(gòu)中非常重要的一個(gè)環(huán)節(jié)。

          確定內(nèi)外部內(nèi)容需求

            此間要深入研究企業(yè)內(nèi)部和外部對內(nèi)容的各種需求,使業(yè)務(wù)可以得到更好的支撐。對于企業(yè)內(nèi)部來說,從內(nèi)容管理中得到較多的是企業(yè)決策管理者、銷售和市場部門、客戶服務(wù)和技術(shù)支持部門、研究與開發(fā)部門的資源。對于企業(yè)外部來說,內(nèi)容管理應(yīng)該側(cè)重挖掘潛在和現(xiàn)有的客戶、機(jī)構(gòu)和個(gè)人投資者,以及能夠?qū)井a(chǎn)生影響的權(quán)威人士等信息。依據(jù)他們對于內(nèi)容的需求,就可以制定出知識(shí)在企業(yè)業(yè)務(wù)中的需求藍(lán)圖,來描述內(nèi)容、業(yè)務(wù)、人員之間的關(guān)系。

          確定策略確定產(chǎn)品確定實(shí)施計(jì)劃

            滿足各部門和人員的內(nèi)容需求,需要從內(nèi)容建設(shè)和建設(shè)內(nèi)容管理系統(tǒng)入手。內(nèi)容建設(shè)包括是否購買外部的內(nèi)容,怎樣將現(xiàn)有的內(nèi)容重新整理,以滿足新的需求或者滿足不同人員的需求,怎樣進(jìn)行研發(fā)創(chuàng)新等;建設(shè)內(nèi)容管理系統(tǒng),并采取切實(shí)可行的措施,以確保應(yīng)用。這樣,就首先要確定內(nèi)容管理系統(tǒng)的建設(shè)策略,然后要進(jìn)行產(chǎn)品和技術(shù)方案的選擇。在技術(shù)路線確定以后,可根據(jù)產(chǎn)品的特點(diǎn)、內(nèi)容管理的要求,制定出系統(tǒng)的實(shí)施計(jì)劃,以指導(dǎo)系統(tǒng)的建設(shè)。

          建設(shè)好內(nèi)容管理系統(tǒng)確保應(yīng)用

            為了確保內(nèi)容管理系統(tǒng)的有效應(yīng)用,可以事先選定一二個(gè)部門進(jìn)行試點(diǎn)。此間,要注意多種內(nèi)容獲取渠道的集成,僅將內(nèi)容存儲(chǔ)好是遠(yuǎn)遠(yuǎn)不夠的,用戶應(yīng)該能通過多種渠道、多種形式獲得所需的信息;還要注意與其它系統(tǒng)進(jìn)行有效的集成,包括與OA系統(tǒng)、郵件系統(tǒng)、ERP、CRM等業(yè)務(wù)系統(tǒng)的集成,同時(shí)在集成時(shí),還要綜合考慮需求的強(qiáng)烈程度、成本等諸多因素,按收益成本最大化的原則進(jìn)行集成。

          posted @ 2008-05-07 13:36 狼愛上貍 閱讀(333) | 評(píng)論 (0)編輯 收藏

          一只兔子如何吃掉狼的

                  一天,一只兔子在山洞前寫文章,一只狼走了過來,問:“兔子啊,你在干什么?”答曰:“寫文章。”問:“什么題目?”答曰:“《淺談兔子是怎樣吃掉狼的》。”狼哈哈大笑,表示不信,于是兔子把狼領(lǐng)進(jìn)山洞。過了一會(huì),兔子獨(dú)自走出山洞,繼續(xù)寫文章。一只野豬走了過來,問:“兔子你在寫什么?”答:“文 章。”問:“題目是什么?”答:“《淺談兔子是如何把野豬吃掉的》。”野豬不信,于是同樣的事情發(fā)生。

                  最后,在山洞里,一只獅子在一堆白骨之間,滿意的剔著牙讀著兔子交給它的文章,題目:“《一只動(dòng)物,能力大小關(guān)鍵要看你的老板是誰》。”

            這只兔子有次不小心告訴了他的一個(gè)兔子朋友,這消息逐漸在森林中傳播;獅子知道后非常生氣,他告訴兔子:“如果這個(gè)星期沒有食物進(jìn)洞,我就吃你。”于是兔子繼續(xù)在洞口寫文章。一只小鹿走過來,“兔子,你在干什么啊?”“寫文章”“什么題目”““《淺談兔子是怎樣吃掉狼的》”。“哈哈,這個(gè)事情全森林都知道啊,你別胡弄我了,我是不會(huì)進(jìn)洞的”。“我馬上要退休了,獅子說要找個(gè)人頂替我,難道你不想這篇文章的兔子變成小鹿么”。小鹿想了想,終于忍不住誘惑,跟隨兔子走進(jìn)洞里。過了一會(huì),兔子獨(dú)自走出山洞,繼續(xù)寫文章。一只小馬走過來,同樣是事情發(fā)生了。

            最后,在山洞里,一只獅子在一堆白骨之間,滿意的剔著牙讀著兔子交給它的文章,題目是:《如何發(fā)展下線動(dòng)物為老板提供食物》  

                  隨著時(shí)間的推移,獅子越長越大,兔子的食物已遠(yuǎn)遠(yuǎn)不能填飽肚子。一日,他告訴兔子:“我的食物量要加倍,例如:原來4天一只小鹿,現(xiàn)在要2天一只,如果一周之內(nèi)改變不了局面我就吃你。于是,兔子離開洞口,跑進(jìn)森林深處,他見到一只狼,“你相信兔子能輕松吃掉狼嗎”。狼哈哈大笑,表示不信,于是兔子把狼領(lǐng)進(jìn)山洞。過了一會(huì),兔子獨(dú)自走出山洞,繼續(xù)進(jìn)入森林深處。這回他碰到一只野豬----“你相信兔子能輕松吃掉野豬嗎” 。野豬不信,于是同樣的事情發(fā)生了。原來森林深處的動(dòng)物并不知道兔子和獅子的故事。 

            最后,在山洞里,一只獅子在一堆白骨之間,滿意的剔著牙讀著兔子交給它的文章,題目是:《如何實(shí)現(xiàn)由坐商到行商的轉(zhuǎn)型為老板提供更多的食物》  

                  時(shí)間飛快,轉(zhuǎn)眼之間,兔子在森林里的名氣越來越大,因?yàn)榇蠹叶贾浪幸粋€(gè)很歷害的老板。這只小兔開始橫行霸道,欺上欺下,沒有動(dòng)物敢惹。它時(shí)時(shí)想起和烏龜賽跑的羞辱。它找到烏龜說:“三天之內(nèi),見我老板!”揚(yáng)長而去。烏龜難過的哭了,這時(shí)卻碰到了一位獵人,烏龜把這事告訴了他,獵人哈哈大笑。于是森林里發(fā)生了一件重大事情,獵人披著獅子皮和烏龜一起在吃兔子火鍋。

            地下丟了半張紙片歪歪扭扭的寫著:山外青山樓外樓,強(qiáng)中還有強(qiáng)中手啊!! 

                  在很長一段時(shí)間里森林里恢復(fù)了往日的寧靜,兔子吃狼的故事似乎快要被大家忘記了,不過一只年輕的老虎在聽說了這個(gè)故事后,被激發(fā)了靈感。于是他抓住了一只羚羊,對羚羊說,如果你可以象以前的兔子那樣為我?guī)硎澄锬俏揖筒怀阅恪S谑牵缪驘o奈的答應(yīng)了老虎,而老虎也悠然自得的進(jìn)了山洞。可是三天過去了,也沒有見羚羊領(lǐng)一只動(dòng)物進(jìn)洞。他實(shí)在憋不住了,想出來看看情況。羚羊早已不在了,他異常憤怒。

                  正在他暴跳如雷的時(shí)候突然發(fā)現(xiàn)了羚羊?qū)懙囊黄恼拢}目是:《想要做好老板先要懂得怎樣留住員工》。 

          posted @ 2008-05-07 12:53 狼愛上貍 閱讀(207) | 評(píng)論 (0)編輯 收藏

          程序員思維定勢

          1)機(jī)器思維
          優(yōu)秀的程序員最擅長和電腦程序打交道,并通過代碼去控制反饋。而管理需要和人打交道,需要收集人的反饋。電腦是按邏輯來執(zhí)行的,而人卻要復(fù)雜很多,特別是團(tuán)隊(duì)中有女性成員,挑戰(zhàn)難度就更大。由于長期和電腦接觸,很多程序員缺乏和別人溝通的技巧,或者說情商相對較低。這在管理上是比較致命的缺點(diǎn)。

          2)BUG思維
          優(yōu)秀的程序員追求完美,看自己或者別人代碼時(shí)第一反應(yīng)是看什么地方可能有BUG, 管理時(shí)如果帶著BUG思維,就會(huì)只看到別人的不足和錯(cuò)誤,而不去表揚(yáng)其有進(jìn)步的地方。(完美思維的壞處還有一個(gè),就是過于關(guān)注細(xì)節(jié))如果方向和前提有問題,過于關(guān)注細(xì)節(jié)反而會(huì)帶來延誤。

          3)工匠思維
          程序員靠手藝吃飯,創(chuàng)業(yè)總是會(huì)碰到各種困難,在碰到困境的時(shí)候程序員出身的創(chuàng)業(yè)者是有退路的,大不了我再回去寫程序搞技術(shù)好了。創(chuàng)業(yè)最需要的就是堅(jiān)持,需要一種永不言棄的精神氣,不能堅(jiān)持到底,也就不能收獲果實(shí)。

          4)大俠思維
          以技術(shù)創(chuàng)業(yè)起家的容易迷信技術(shù),忽視市場,忽視管理,總以為只有自己的是最好的。遺憾的是技術(shù)變遷實(shí)在太快,一時(shí)的先進(jìn)不能代表永遠(yuǎn)的先進(jìn)。先進(jìn)的技術(shù)也不一定就是致勝的法寶。

          5)邊界思維
          程序員設(shè)計(jì)代碼和系統(tǒng)時(shí),常常會(huì)考慮要處理邊界和異常。反映到思維習(xí)慣上,就是遇到問題,就會(huì)全面的思考各種情況。這是很好的優(yōu)點(diǎn),但做事業(yè)時(shí),這有時(shí)候反而會(huì)是缺點(diǎn)。

          上面五類有不少具體例子,大家也可以看看自己的思維習(xí)慣里面是不是這樣?
          習(xí)慣是很難改變的,最好的處理方式是找到搭檔,能彌補(bǔ)自己的不足,這樣成功的概率才會(huì)加大。




          來自:http://www.blog.edu.cn/user3/KingThie/archives/2007/1822533.shtml

          posted @ 2008-05-07 12:52 狼愛上貍 閱讀(241) | 評(píng)論 (0)編輯 收藏

          文件系統(tǒng)不同步問題resource is out of sync with the file system的解決辦法

          在eclipse中,啟動(dòng)run on server時(shí)報(bào)錯(cuò):
          Resource is out of sync with the file system: '/Test_1_Struts_Spring_Hibernate/WebContent/WEB-INF/.struts-config.xml.strutside'.

          查閱資料后發(fā)現(xiàn)這是文件系統(tǒng)不同步的問題,是因?yàn)樵趀clipse之外對工程中的resource進(jìn)行修改引起的;但是,有時(shí)沒有在eclipse之外進(jìn)行修改,也會(huì)報(bào)類似的錯(cuò)誤。
          解決辦法:需要手動(dòng)刷新一下資源管理器。
          (1)在eclipse中,工程目錄右鍵,選擇F5(refresh)
          (2)設(shè)置eclipse自動(dòng)刷新。
                     通過Window->Preferences->General->Workspace,選中Refresh automatically。

          來自:http://hi.baidu.com/proglife/blog/item/0c14d0d9ad404e2910df9b3a.html

          posted @ 2008-05-03 13:19 狼愛上貍 閱讀(4608) | 評(píng)論 (9)編輯 收藏

          dbstart&dbshut腳本中的錯(cuò)誤

          Oracle提供了兩個(gè)腳本dbstart和dbshut用來啟動(dòng)和關(guān)閉數(shù)據(jù)庫.
          這兩個(gè)腳本首先讀取oratab(/etc/oratab)文件來決定哪個(gè)數(shù)據(jù)庫是需要自動(dòng)啟動(dòng)和關(guān)閉,然后啟動(dòng)和關(guān)閉那些數(shù)據(jù)庫,
          oratab文件通過root.sh創(chuàng)建.

          [oracle@chicago oracle]$ cat /etc/oratab
          #

          # This file is used by ORACLE utilities. It is created by root.sh
          # and updated by the Database Configuration Assistant when creating
          # a database.

          # A colon, ':', is used as the field terminator. A new line terminates
          # the entry. Lines beginning with a pound sign, '#', are comments.
          #
          # Entries are of the form:
          # $ORACLE_SID:$ORACLE_HOME:<N|Y>:
          #
          # The first and second fields are the system identifier and home
          # directory of the database respectively. The third filed indicates
          # to the dbstart utility that the database should , "Y", or should not,
          # "N", be brought up at system boot time.
          #
          # Multiple entries with the same $ORACLE_SID are not allowed.
          #
          #
          orcl:/u01/app/oracle/oracle/product/10.2.0/db_1:Y

          不過,dbstart/dbshut腳本中都包含有錯(cuò)誤.
          需要修改ORACLE_HOME_LISTNER=$ORACLE_HOME
          [oracle@chicago oracle]$ dbstart
          ORACLE_HOME_LISTNER is not SET, unable to auto-start Oracle Net Listener
          Usage: /u01/app/oracle/oracle/product/10.2.0/db_1/bin/dbstart ORACLE_HOME

          [oracle@chicago oracle]$ vi $ORACLE_HOME/bin/dbstart

          :
          #
          # $Id: dbstart.sh.pp 25-may-2005.14:52:00 vikrkuma Exp $
          # Copyright (c) 1991, 2005, Oracle. All rights reserved.
          #

          ###################################
          #
          # usage: dbstart $ORACLE_HOME
          #
          # This script is used to start ORACLE from /etc/rc(.local).
          # It should ONLY be executed as part of the system boot procedure.
          #
          # This script will start all databases listed in the oratab file
          # whose third field is a "Y". If the third field is set to "Y" and
          # there is no ORACLE_SID for an entry (the first field is a *),
          # then this script will ignore that entry.
          #
          # This script requires that ASM ORACLE_SID's start with a +, and
          # that non-ASM instance ORACLE_SID's do not start with a +.
          #
          # If ASM instances are to be started with this script, it cannot
          # be used inside an rc*.d directory, and should be invoked from
          # rc.local only. Otherwise, the CSS service may not be available
          # yet, and this script will block init from completing the boot
          # cycle.
          #
          # If you want dbstart to auto-start a single-instance database that uses
          # an ASM server that is auto-started by CRS (this is the default behavior
          # for an ASM cluster), you must change the database's ORATAB entry to use
          # a third field of "W" and the ASM's ORATAB entry to use a third field of "N".
          # These values specify that dbstart auto-starts the database only after
          # the ASM instance is up and running.
          #
          # Note:
          # Use ORACLE_TRACE=T for tracing this script.
          #
          # The progress log for each instance bringup plus Error and Warning message[s]
          # are logged in file $ORACLE_HOME/startup.log. The error messages related to
          # instance bringup are also logged to syslog (system log module).
          # The Listener log is located at $ORACLE_HOME_LISTNER/listener.log
          #
          # To configure:
          # 1) Set ORATAB:
          # On Solaris
          # ORATAB=/var/opt/oracle/oratab
          # All other UNIX platforms
          # ORATAB=/etc/oratab
          #
          # 2) Update $ORATAB/oratab with Database Instances that need to be started up.
          # Entries are of the form:
          # $ORACLE_SID:$ORACLE_HOME:<N|Y|W>:
          # An example entry:
          # main:/usr/lib/oracle/emagent_10g:Y
          #
          # Overall algorithm:
          # 1) Bring up all ASM instances with 'Y' entry in status field in oratab entry
          # 2) Bring up all Database instances with 'Y' entry in status field in
          # oratab entry
          # 3) If there are Database instances with 'W' entry in status field
          # then
          # iterate over all ASM instances (irrespective of 'Y' or 'N') AND
          # wait for all of them to be started
          # fi
          # 4) Bring up all Database instances with 'W' entry in status field in
          # oratab entry
          #
          #####################################

          LOGMSG="logger -puser.alert -s "

          trap 'exit' 1 2 3

          # for script tracing
          case $ORACLE_TRACE in
          T) set -x ;;
          esac

          # Set path if path not set (if called from /etc/rc)
          case $PATH in
          "") PATH=/bin:/usr/bin:/etc
          export PATH ;;
          esac
          # Save LD_LIBRARY_PATH
          SAVE_LLP=$LD_LIBRARY_PATH

          # First argument is used to bring up Oracle Net Listener
          ORACLE_HOME_LISTNER=$ORACLE_HOME
          if [ ! $ORACLE_HOME_LISTNER ] ; then
          echo "ORACLE_HOME_LISTNER is not SET, unable to auto-start Oracle Net Listener"
          echo "Usage: $0 ORACLE_HOME"
          else
          LOG=$ORACLE_HOME_LISTNER/listener.log

          # Start Oracle Net Listener
          if [ -x $ORACLE_HOME_LISTNER/bin/tnslsnr ] ; then
          echo "$0: Starting Oracle Net Listener" >> $LOG 2>&1
          "/u01/app/oracle/oracle/product/10.2.0/db_1/bin/dbstart" 461L, 13926C written
          [oracle@chicago oracle]$ dbstart
          Processing Database instance "orcl": log file /u01/app/oracle/oracle/product/10.2.0/db_1/startup.log
          [oracle@chicago oracle]$ dbshut
          ORACLE_HOME_LISTNER is not SET, unable to auto-stop Oracle Net Listener
          Usage: /u01/app/oracle/oracle/product/10.2.0/db_1/bin/dbshut ORACLE_HOME
          Processing Database instance "orcl": log file /u01/app/oracle/oracle/product/10.2.0/db_1/shutdown.log
          [oracle@chicago oracle]$ vi $ORACLE_HOME/bin/dbshut

          :
          #
          # $Id: dbshut.sh.pp 11-may-2005.19:37:00 vikrkuma Exp $
          # Copyright (c) 1991, 2005, Oracle. All rights reserved.
          #

          ###################################
          #
          # usage: dbshut $ORACLE_HOME
          #
          # This script is used to shutdown ORACLE from /etc/rc(.local).
          # It should ONLY be executed as part of the system boot procedure.
          #
          # This script will shutdown all databases listed in the oratab file
          # whose third field is a "Y" or "W". If the third field is set to "Y" and
          # there is no ORACLE_SID for an entry (the first field is a *),
          # then this script will ignore that entry.
          #
          # This script requires that ASM ORACLE_SID's start with a +, and
          # that non-ASM instance ORACLE_SID's do not start with a +.
          #
          # Note:
          # Use ORACLE_TRACE=T for tracing this script.
          # Oracle Net Listener is also shutdown using this script.
          #
          # The progress log for each instance shutdown is logged in file
          # $ORACLE_HOME/shutdown.log.
          #
          # To configure:
          # 1) Set ORATAB:
          # On Solaris
          # ORATAB=/var/opt/oracle/oratab
          # All other UNIX platforms
          # ORATAB=/etc/oratab
          #
          # 2) Update $ORATAB/oratab with Database Instances that need to be shutdown.
          # Entries are of the form:
          # $ORACLE_SID:$ORACLE_HOME:<N|Y>:
          # An example entry:
          # main:/usr/lib/oracle/emagent_10g:Y
          #
          # Note:
          # Use ORACLE_TRACE=T for tracing this script.
          # Oracle Net Listener is NOT shutdown using this script.
          #
          # The progress log for each instance shutdown is logged in file
          # $ORACLE_HOME/shutdown.log.
          #
          # To configure:
          # 1) Set ORATAB:
          # On Solaris
          # ORATAB=/var/opt/oracle/oratab
          # All other UNIX platforms
          # ORATAB=/etc/oratab
          #
          # 2) Update $ORATAB/oratab with Database Instances that need to be shutdown.
          # Entries are of the form:
          # $ORACLE_SID:$ORACLE_HOME:<N|Y>:
          # An example entry:
          # main:/usr/lib/oracle/emagent_10g:Y
          #
          #####################################

          trap 'exit' 1 2 3
          case $ORACLE_TRACE in
          T) set -x ;;
          esac
          # Set path if path not set (if called from /etc/rc)
          case $PATH in
          "") PATH=/bin:/usr/bin:/etc
          export PATH ;;
          esac
          # Save LD_LIBRARY_PATH
          SAVE_LLP=$LD_LIBRARY_PATH

          # The this to bring down Oracle Net Listener
          ORACLE_HOME_LISTNER=$ORACLE_HOME
          if [ ! $ORACLE_HOME_LISTNER ] ; then
          echo "ORACLE_HOME_LISTNER is not SET, unable to auto-stop Oracle Net Listener"
          echo "Usage: $0 ORACLE_HOME"
          else
          LOG=$ORACLE_HOME_LISTNER/listener.log

          # Stop Oracle Net Listener
          if [ -f $ORACLE_HOME_LISTNER/bin/tnslsnr ] ; then
          "/u01/app/oracle/oracle/product/10.2.0/db_1/bin/dbshut" 246L, 6592C written
          [oracle@chicago oracle]$ dbstart
          Processing Database instance "orcl": log file /u01/app/oracle/oracle/product/10.2.0/db_1/startup.log
          [oracle@chicago oracle]$ dbshut
          Processing Database instance "orcl": log file /u01/app/oracle/oracle/product/10.2.0/db_1/shutdown.log
          [oracle@chicago oracle]$

          來自:http://benbo.itpub.net/post/26034/311306

          posted @ 2008-05-02 17:30 狼愛上貍 閱讀(2090) | 評(píng)論 (3)編輯 收藏

          我的ubuntu8.04安裝經(jīng)驗(yàn)

               摘要: Ubuntu 8.04 LTS(長期支持版)免費(fèi)光盤已經(jīng)接受預(yù)定! https://shipit.ubuntu.com/有刻錄機(jī)的最好自己刻盤,體諒人家. 總綱:分以下幾部分工作 (更新截至4月27日,決定停止更新,文章寫長了就沒意思了,眼花,啰嗦) 作者 pengkuny 原始鏈接 http://www.pengkuny.com/post/Install_Ubuntu8.04.html ...  閱讀全文

          posted @ 2008-04-29 20:01 狼愛上貍 閱讀(5956) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共38頁: First 上一頁 19 20 21 22 23 24 25 26 27 下一頁 Last 
          主站蜘蛛池模板: 锦屏县| 雷州市| 建阳市| 博罗县| 全州县| 龙南县| 禄丰县| 武乡县| 淮阳县| 云龙县| 镇雄县| 盱眙县| 郧西县| 宜昌市| 平舆县| 平度市| 遂昌县| 泽州县| 略阳县| 佛坪县| 安阳市| 子洲县| 胶州市| 平乡县| 丹巴县| 瓦房店市| 资源县| 馆陶县| 尖扎县| 靖西县| 额尔古纳市| 宁安市| 宁强县| 馆陶县| 河南省| 德清县| 黔东| 青冈县| 新密市| 芦溪县| 平邑县|