<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java-Android-jwebee
    Java-Android-jwebee
    對IT人來說,要成為一個優秀的技術型管理者,除了需要具備扎實的技術基礎之外,還應該培養良好的人際關系能力、談判與溝通技能、客戶關系與咨詢技能、商業頭腦和財務技能以及創新意識,此外還要有巧妙的激勵技巧和化解沖突與解決突發問題的能力.
    1 什么是單點登陸
    單點登錄( Single Sign On ),簡稱為 SSO ,是目前比較流行的企業業務整合的解決方案之一。 SSO 的定義是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。
    較大的企業內部,一般都有很多的業務支持系統為其提供相應的管理和 IT 服務。例如財務系統為財務人員提供財務的管理、計算和報表服務;人事系統為人事部門提供全公司人員的維護服務;各種業務系統為公司內部不同的業務提供不同的服務等等。這些系統的目的都是讓計算機來進行復雜繁瑣的計算工作,來替代人力的手工勞動,提高工作效率和質量。這些不同的系統往往是在不同的時期建設起來的,運行在不同的平臺上;也許是由不同廠商開發,使用了各種不同的技術和標準。如果舉例說國內一著名的 IT 公司(名字隱去),內部共有 60 多個業務系統,這些系統包括兩個不同版本的 SAP ERP 系統, 12 個不同類型和版本的數據庫系統, 8 個不同類型和版本的操作系統,以及使用了 3 種不同的防火墻技術,還有數十種互相不能兼容的協議和標準,你相信嗎?不要懷疑,這種情況其實非常普遍。每一個應用系統在運行了數年以后,都會成為不可替換的企業 IT 架構的一部分,如下圖所示。
    隨著企業的發展,業務系統的數量在不斷的增加,老的系統卻不能輕易的替換,這會帶來很多的開銷。其一是管理上的開銷,需要維護的系統越來越多。很多系統的數據是相互冗余和重復的,數據的不一致性會給管理工作帶來很大的壓力。業務和業務之間的相關性也越來越大,例如公司的計費系統和財務系統,財務系統和人事系統之間都不可避免的有著密切的關系。
    為了降低管理的消耗,最大限度的重用已有投資的系統,很多企業都在進行著企業應用集成( EAI )。企業應用集成可以在不同層面上進行:例如在數據存儲層面上的“數據大集中”,在傳輸層面上的“通用數據交換平臺”,在應用層面上的“業務流程整合”,和用戶界面上的“通用企業門戶”等等。事實上,還用一個層面上的集成變得越來越重要,那就是“身份認證”的整合,也就是“單點登錄”。
    通常來說,每個單獨的系統都會有自己的安全體系和身份認證系統。整合以前,進入每個系統都需要進行登錄,這樣的局面不僅給管理上帶來了很大的困難,在安全方面也埋下了重大的隱患。下面是一些著名的調查公司顯示的統計數據:
    • 用戶每天平均 16 分鐘花在身份驗證任務上 - 資料來源: IDS
    • 頻繁的 IT 用戶平均有 21 個密碼 - 資料來源: NTA Monitor Password Survey
    • 49% 的人寫下了其密碼,而 67% 的人很少改變它們
    • 79 秒出現一起身份被竊事件 - 資料來源:National Small Business Travel Assoc
    • 全球欺騙損失每年約 12B - 資料來源:Comm Fraud Control Assoc
    • 2007 年,身份管理市場將成倍增長至 $4.5B - 資料來源:IDS
    ?
    使用“單點登錄”整合后,只需要登錄一次就可以進入多個系統,而不需要重新登錄,這不僅僅帶來了更好的用戶體驗,更重要的是降低了安全的風險和管理的消耗。請看下面的統計數據:
    • 提高 IT 效率:對于每 1000 個受管用戶,每用戶可節省$70K
    • 幫助臺呼叫減少至少1/3,對于 10K 員工的公司,每年可以節省每用戶 $75,或者合計 $648K
    • 生產力提高:每個新員工可節省 $1K,每個老員工可節省 $350 &O5533; 資料來源:Giga
    • ROI 回報:7.5 13 個月 &O5533; 資料來源:Gartner
    ?
    另外,使用“單點登錄”還是 SOA 時代的需求之一。在面向服務的架構中,服務和服務之間,程序和程序之間的通訊大量存在,服務之間的安全認證是 SOA 應用的難點之一,應此建立“單點登錄”的系統體系能夠大大簡化 SOA 的安全問題,提高服務之間的合作效率。
    2 單點登陸的技術實現機制
    隨著 SSO 技術的流行, SSO 的產品也是滿天飛揚。所有著名的軟件廠商都提供了相應的解決方案。在這里我并不想介紹自己公司( Sun Microsystems )的產品,而是對 SSO 技術本身進行解析,并且提供自己開發這一類產品的方法和簡單演示。
    單點登錄的機制其實是比較簡單的,用一個現實中的例子做比較。頤和園是北京著名的旅游景點,也是我常去的地方。在頤和園內部有許多獨立的景點,例如“蘇州街”、“佛香閣”和“德和園”,都可以在各個景點門口單獨買票。很多游客需要游玩所有德景點,這種買票方式很不方便,需要在每個景點門口排隊買票,錢包拿進拿出的,容易丟失,很不安全。于是絕大多數游客選擇在大門口買一張通票(也叫套票),就可以玩遍所有的景點而不需要重新再買票。他們只需要在每個景點門口出示一下剛才買的套票就能夠被允許進入每個獨立的景點。
    單點登錄的機制也一樣,如下圖所示,當用戶第一次訪問應用系統 1 的時候,因為還沒有登錄,會被引導到認證系統中進行登錄( 1 );根據用戶提供的登錄信息,認證系統進行身份效驗,如果通過效驗,應該返回給用戶一個認證的憑據-- ticket 2 );用戶再訪問別的應用的時候( 3 5 )就會將這個 ticket 帶上,作為自己認證的憑據,應用系統接受到請求之后會把 ticket 送到認證系統進行效驗,檢查 ticket 的合法性( 4 6 )。如果通過效驗,用戶就可以在不用再次登錄的情況下訪問應用系統 2 和應用系統 3 了。
    從上面的視圖可以看出,要實現 SSO ,需要以下主要的功能:
    • 所有應用系統共享一個身份認證系統。
      統一的認證系統是 SSO 的前提之一。認證系統的主要功能是將用戶的登錄信息和用戶信息庫相比較,對用戶進行登錄認證;認證成功后,認證系統應該生成統一的認證標志( ticket ),返還給用戶。另外,認證系統還應該對 ticket 進行效驗,判斷其有效性。
    • 所有應用系統能夠識別和提取 ticket 信息
      要實現 SSO 的功能,讓用戶只登錄一次,就必須讓應用系統能夠識別已經登錄過的用戶。應用系統應該能對 ticket 進行識別和提取,通過與認證系統的通訊,能自動判斷當前用戶是否登錄過,從而完成單點登錄的功能。
    ?
    上面的功能只是一個非常簡單的 SSO 架構,在現實情況下的 SSO 有著更加復雜的結構。有兩點需要指出的是:
    • 單一的用戶信息數據庫并不是必須的,有許多系統不能將所有的用戶信息都集中存儲,應該允許用戶信息放置在不同的存儲中,如下圖所示。事實上,只要統一認證系統,統一 ticket 的產生和效驗,無論用戶信息存儲在什么地方,都能實現單點登錄。
    ?
    • 統一的認證系統并不是說只有單個的認證服務器,如下圖所示,整個系統可以存在兩個以上的認證服務器,這些服務器甚至可以是不同的產品。認證服務器之間要通過標準的通訊協議,互相交換認證信息,就能完成更高級別的單點登錄。如下圖,當用戶在訪問應用系統 1 時,由第一個認證服務器進行認證后,得到由此服務器產生的 ticket 。當他訪問應用系統 4 的時候,認證服務器 2 能夠識別此 ticket 是由第一個服務器產生的,通過認證服務器之間標準的通訊協議(例如 SAML )來交換認證信息,仍然能夠完成 SSO 的功能。
    ?
    3 WEB-SSO 的實現
    隨著互聯網的高速發展, WEB 應用幾乎統治了絕大部分的軟件應用系統,因此 WEB-SSO SSO 應用當中最為流行。 WEB-SSO 有其自身的特點和優勢,實現起來比較簡單易用。很多商業軟件和開源軟件都有對 WEB-SSO 的實現。其中值得一提的是 OpenSSO https://opensso.dev.java.net/ ),為用 Java 實現 WEB-SSO 提供架構指南和服務指南,為用戶自己來實現 WEB-SSO 提供了理論的依據和實現的方法。
    為什么說 WEB-SSO 比較容易實現呢?這是有 WEB 應用自身的特點決定的。
    眾所周知, Web 協議(也就是 HTTP )是一個無狀態的協議。一個 Web 應用由很多個 Web 頁面組成,每個頁面都有唯一的 URL 來定義。用戶在瀏覽器的地址欄輸入頁面的 URL ,瀏覽器就會向 Web Server 去發送請求。如下圖,瀏覽器向 Web 服務器發送了兩個請求,申請了兩個頁面。這兩個頁面的請求是分別使用了兩個單獨的 HTTP 連接。所謂無狀態的協議也就是表現在這里,瀏覽器和 Web 服務器會在第一個請求完成以后關閉連接通道,在第二個請求的時候重新建立連接。 Web 服務器并不區分哪個請求來自哪個客戶端,對所有的請求都一視同仁,都是單獨的連接。這樣的方式大大區別于傳統的( Client/Server C/S 結構 , 在那樣的應用中,客戶端和服務器端會建立一個長時間的專用的連接通道。正是因為有了無狀態的特性,每個連接資源能夠很快被其他客戶端所重用,一臺 Web 服務器才能夠同時服務于成千上萬的客戶端。
    但是我們通常的應用是有狀態的。先不用提不同應用之間的 SSO ,在同一個應用中也需要保存用戶的登錄身份信息。例如用戶在訪問頁面 1 的時候進行了登錄,但是剛才也提到,客戶端的每個請求都是單獨的連接,當客戶再次訪問頁面 2 的時候,如何才能告訴 Web 服務器,客戶剛才已經登錄過了呢?瀏覽器和服務器之間有約定:通過使用 cookie 技術來維護應用的狀態。 Cookie 是可以被 Web 服務器設置的字符串,并且可以保存在瀏覽器中。如下圖所示,當瀏覽器訪問了頁面 1 時, web 服務器設置了一個 cookie ,并將這個 cookie 和頁面 1 一起返回給瀏覽器,瀏覽器接到 cookie 之后,就會保存起來,在它訪問頁面 2 的時候會把這個 cookie 也帶上, Web 服務器接到請求時也能讀出 cookie 的值,根據 cookie 值的內容就可以判斷和恢復一些用戶的信息狀態。
    Web-SSO 完全可以利用 Cookie 結束來完成用戶登錄信息的保存,將瀏覽器中的 Cookie 和上文中的 Ticket 結合起來,完成 SSO 的功能。
    ?
    為了完成一個簡單的 SSO 的功能,需要兩個部分的合作:
    1. 統一的身份認證服務。
    2. 修改 Web 應用,使得每個應用都通過這個統一的認證服務來進行身份效驗。
    3.1 Web SSO 的樣例
    根據上面的原理,我用 J2EE 的技術( JSP Servlet )完成了一個具有 Web-SSO 的簡單樣例。樣例包含一個身份認證的服務器和兩個簡單的 Web 應用,使得這兩個 Web 應用通過統一的身份認證服務來完成 Web-SSO 的功能。此樣例所有的源代碼和二進制代碼都可以從網站地址 http://gceclub.sun.com.cn/wangyu/ 下載。
    ?
    樣例下載、安裝部署和運行指南:
    • Web-SSO 的樣例是由三個標準 Web 應用組成,壓縮成三個 zip 文件,從 http://gceclub.sun.com.cn/wangyu// 中下載。其中 SSOAuth http://gceclub.sun.com.cn/wangyu/ )是身份認證服務; SSOWebDemo1 http://gceclub.sun.com.cn/wangyu/ )和 SSOWebDemo2 http://gceclub.sun.com.cn/wangyu/ )是兩個用來演示單點登錄的 Web 應用。這三個 Web 應用之所以沒有打成 war 包,是因為它們不能直接部署,根據讀者的部署環境需要作出小小的修改。樣例部署和運行的環境有一定的要求,需要符合 Servlet2.3 以上標準的 J2EE 容器才能運行(例如 Tomcat5,Sun Application Server 8, Jboss 4 等)。另外,身份認證服務需要 JDK1.5 的運行環境。之所以要用 JDK1.5 是因為筆者使用了一個線程安全的高性能的 Java 集合類“ ConcurrentMap” ,只有在 JDK1.5 中才有。
    • 這三個 Web 應用完全可以單獨部署,它們可以分別部署在不同的機器,不同的操作系統和不同的 J2EE 的產品上,它們完全是標準的和平臺無關的應用。但是有一個限制,那兩臺部署應用( demo1 demo2 )的機器的域名需要相同,這在后面的章節中會解釋到 cookie domain 的關系以及如何制作跨域的 WEB-SSO
    • 解壓縮 SSOAuth.zip 文件,在 /WEB-INF/ 下的 web.xml 中請修改“ domainname” 的屬性以反映實際的應用部署情況, domainname 需要設置為兩個單點登錄的應用( demo1 demo2 )所屬的域名。這個 domainname 和當前 SSOAuth 服務部署的機器的域名沒有關系。我缺省設置的是“ .sun.com” 。如果你部署 demo1 demo2 的機器沒有域名,請輸入 IP 地址或主機名(如 localhost ),但是如果使用 IP 地址或主機名也就意味著 demo1 demo2 需要部署到一臺機器上了。設置完后,根據你所選擇的 J2EE 容器,可能需要將 SSOAuth 這個目錄壓縮打包成 war 文件。用“ jar -cvf SSOAuth.war SSOAuth/” 就可以完成這個功能。
    • 解壓縮 SSOWebDemo1 SSOWebDemo2 文件,分別在它們 /WEB-INF/ 下找到 web.xml 文件,請修改其中的幾個初始化參數
      <init-param>
      <param-name>SSOServiceURL</param-name>
      <param-value>http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth</param-value>
      </init-param>
      <init-param>
      <param-name>SSOLoginPage</param-name>
      <param-value>http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp</param-value>
      </init-param>
      將其中的 SSOServiceURL SSOLoginPage 修改成部署 SSOAuth 應用的機器名、端口號以及根路徑(缺省是 SSOAuth )以反映實際的部署情況。設置完后,根據你所選擇的 J2EE 容器,可能需要將 SSOWebDemo1 SSOWebDemo2 這兩個目錄壓縮打包成兩個 war 文件。用“ jar -cvf SSOWebDemo1.war SSOWebDemo1/” 就可以完成這個功能。
    • 請輸入第一個 web 應用的測試 URL test.jsp , 例如 http://wangyu.prc.sun.com:8080/ SSOWebDemo1/test.jsp ,如果是第一次訪問,便會自動跳轉到登錄界面,如下圖

    • 使用系統自帶的三個帳號之一登錄(例如,用戶名: wangyu, 密碼: wangyu ),便能成功的看到 test.jsp 的內容:顯示當前用戶名和歡迎信息。
    • 請接著在同一個瀏覽器中輸入第二個 web 應用的測試 URL test.jsp , 例如 http://wangyu.prc.sun.com:8080/ SSOWebDemo2/test.jsp 。你會發現,不需要再次登錄就能看到 test.jsp 的內容,同樣是顯示當前用戶名和歡迎信息,而且歡迎信息中明確的顯示當前的應用名稱( demo2 )。
    ?
    3.2 WEB-SSO 代碼講解
    3.2.1 身份認證服務代碼解析
    Web-SSO 的源代碼可以從網站地址 http://gceclub.sun.com.cn/wangyu/web-sso/websso_src.zip 下載。身份認證服務是一個標準的 web 應用,包括一個名為 SSOAuth Servlet ,一個 login.jsp 文件和一個 failed.html 。身份認證的所有服務幾乎都由 SSOAuth Servlet 來實現了; login.jsp 用來顯示登錄的頁面(如果發現用戶還沒有登錄過); failed.html 是用來顯示登錄失敗的信息(如果用戶的用戶名和密碼與信息數據庫中的不一樣)。
    SSOAuth 的代碼如下面的列表顯示,結構非常簡單,先看看這個 Servlet 的主體部分
    package DesktopSSO;
    ?
    import java.io.*;
    import java.net.*;
    import java.text.*;
    import java.util.*;
    import java.util.concurrent.*;
    ?
    import javax.servlet.*;
    import javax.servlet.http.*;
    ?
    ?
    public class SSOAuth extends HttpServlet {
    ???
    ??? static private ConcurrentMap accounts;
    ??? static private ConcurrentMap SSOIDs;
    ??? String cookiename="WangYuDesktopSSOID";
    ??? String domainname;
    ???
    ??? public void init(ServletConfig config) throws ServletException {
    ??????? super.init(config);
    ??????? domainname= config.getInitParameter("domainname");
    ??????? cookiename = config.getInitParameter("cookiename");
    ??????? SSOIDs = new ConcurrentHashMap();
    ??????? accounts=new ConcurrentHashMap();
    ??????? accounts.put("wangyu", "wangyu");
    ??????? accounts.put("paul", "paul");
    ??????? accounts.put("carol", "carol");
    ??? }
    ?
    ??? protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ??????? PrintWriter out = response.getWriter();
    ??????? String action = request.getParameter("action");
    ??????? String result="failed";
    ??????? if (action==null) {
    ??????????? handlerFromLogin(request,response);
    ??????? } else if (action.equals("authcookie")){
    ??????????? String myCookie = request.getParameter("cookiename");
    ??????????? if (myCookie != null)?result = authCookie(myCookie);
    ??????????? out.print(result);
    ??????????? out.close();
    ??????? } else if (action.equals("authuser")) {
    ??????????? result=authNameAndPasswd(request,response);
    ??????????? out.print(result);
    ??????????? out.close();
    ??????? }?else if (action.equals("logout")) {
    ??????????? String myCookie = request.getParameter("cookiename");
    ??????????? logout(myCookie);
    ?? ????????? out.close();
    ??????? }
    ??? }
    ?
    .....
    ?
    }
    ?
    從代碼很容易看出, SSOAuth 就是一個簡單的 Servlet 。其中有兩個靜態成員變量: accounts SSOIDs ,這兩個成員變量都使用了 JDK1.5 中線程安全的 MAP 類: ConcurrentMap ,所以這個樣例一定要 JDK1.5 才能運行。 Accounts 用來存放用戶的用戶名和密碼,在 init() 的方法中可以看到我給系統添加了三個合法的用戶。在實際應用中, accounts 應該是去數據庫中或 LDAP 中獲得,為了簡單起見,在本樣例中我使用了 ConcurrentMap 在內存中用程序創建了三個用戶。而 SSOIDs 保存了在用戶成功的登錄后所產生的 cookie 和用戶名的對應關系。它的功能顯而易見:當用戶成功登錄以后,再次訪問別的系統,為了鑒別這個用戶請求所帶的 cookie 的有效性,需要到 SSOIDs 中檢查這樣的映射關系是否存在。
    ?
    在主要的請求處理方法 processRequest() 中,可以很清楚的看到 SSOAuth 的所有功能
    1. 如果用戶還沒有登錄過,是第一次登錄本系統,會被跳轉到 login.jsp 頁面(在后面會解釋如何跳轉)。用戶在提供了用戶名和密碼以后,就會用 handlerFromLogin() 這個方法來驗證。
    2. 如果用戶已經登錄過本系統,再訪問別的應用的時候,是不需要再次登錄的。因為瀏覽器會將第一次登錄時產生的 cookie 和請求一起發送。效驗 cookie 的有效性是 SSOAuth 的主要功能之一。
    3. SSOAuth 還能直接效驗非 login.jsp 頁面過來的用戶名和密碼的效驗請求。這個功能是用于非 web 應用的 SSO ,這在后面的桌面 SSO 中會用到。
    4. SSOAuth 還提供 logout 服務。
    ?
    下面看看幾個主要的功能函數:
    ? private void handlerFromLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ??????? String username = request.getParameter("username");
    ??????? String password = request.getParameter("password");
    ??????? String pass = (String)accounts.get(username);
    ??????? if ((pass==null)||(!pass.equals(password)))
    ??????????? getServletContext().getRequestDispatcher("/failed.html").forward(request, response);
    ??????? else {
    ??????????? String gotoURL = request.getParameter("goto");
    ??????????? String newID = createUID();
    ??????????? SSOIDs.put(newID, username);
    ??????????? Cookie wangyu = new Cookie(cookiename, newID);
    ??????????? wangyu.setDomain(domainname);
    ??????????? wangyu.setMaxAge(60000);
    ??????????? wangyu.setValue(newID);
    ??????????? wangyu.setPath("/");
    ??????????? response.addCookie(wangyu);
    ??????????? System.out.println("login success, goto back url:" + gotoURL);
    ??????????? if (gotoURL != null) {
    ??????????????? PrintWriter out = response.getWriter();
    ???? ??????????? response.sendRedirect(gotoURL);
    ??????????????? out.close();
    ??????????? }
    ??????? }??
    ??? }
    handlerFromLogin() 這個方法是用來處理來自 login.jsp 的登錄請求。它的邏輯很簡單:將用戶輸入的用戶名和密碼與預先設定好的用戶集合(存放在 accounts 中)相比較,如果用戶名或密碼不匹配的話,則返回登錄失敗的頁面( failed.html ),如果登錄成功的話,需要為用戶當前的 session 創建一個新的 ID ,并將這個 ID 和用戶名的映射關系存放到 SSOIDs 中,最后還要將這個 ID 設置為瀏覽器能夠保存的 cookie 值。
    登錄成功后,瀏覽器會到哪個頁面呢?那我們回顧一下我們是如何使用身份認證服務的。一般來說我們不會直接訪問身份服務的任何 URL ,包括 login.jsp 。身份服務是用來保護其他應用服務的,用戶一般在訪問一個受 SSOAuth 保護的 Web 應用的某個 URL 時,當前這個應用會發現當前的用戶還沒有登錄,便強制將也頁面轉向 SSOAuth login.jsp ,讓用戶登錄。如果登錄成功后,應該自動的將用戶的瀏覽器指向用戶最初想訪問的那個 URL 。在 handlerFromLogin() 這個方法中,我們通過接收 goto” 這個參數來保存用戶最初訪問的 URL ,成功后便重新定向到這個頁面中。
    另外一個要說明的是,在設置 cookie 的時候,我使用了一個setMaxAge(6000) 的方法。這個方法是用來設置 cookie 的有效期,單位是秒。如果不使用這個方法或者參數為負數的話,當瀏覽器關閉的時候,這個 cookie 就失效了。在這里我給了很大的值( 1000 分鐘),導致的行為是:當你關閉瀏覽器(或者關機),下次再打開瀏覽器訪問剛才的應用,只要在 1000 分鐘之內,就不需要再登錄了。我這樣做是下面要介紹的桌面 SSO 中所需要的功能。
    其他的方法更加簡單,這里就不多解釋了。
    ?
    3.2.2 具有 SSO 功能的 web 應用源代碼解析
    要實現 WEB-SSO 的功能,只有身份認證服務是不夠的。這點很顯然,要想使多個應用具有單點登錄的功能,還需要每個應用本身的配合:將自己的身份認證的服務交給一個統一的身份認證服務- SSOAuth SSOAuth 服務中提供的各個方法就是供每個加入 SSO Web 應用來調用的。
    一般來說, Web 應用需要 SSO 的功能,應該通過以下的交互過程來調用身份認證服務的提供的認證服務:
    • Web 應用中每一個需要安全保護的 URL 在訪問以前,都需要進行安全檢查,如果發現沒有登錄(沒有發現認證之后所帶的 cookie ),就重新定向到 SSOAuth 中的 login.jsp 進行登錄。
    • 登錄成功后,系統會自動給你的瀏覽器設置 cookie ,證明你已經登錄過了。
    • 當你再訪問這個應用的需要保護的 URL 的時候,系統還是要進行安全檢查的,但是這次系統能夠發現相應的 cookie
    • 有了這個 cookie ,還不能證明你就一定有權限訪問。因為有可能你已經 logout, 或者 cookie 已經過期了,或者身份認證服務重起過,這些情況下,你的 cookie 都可能無效。應用系統拿到這個 cookie ,還需要調用身份認證的服務,來判斷 cookie 時候真的有效,以及當前的 cookie 對應的用戶是誰。
    • 如果 cookie 效驗成功,就允許用戶訪問當前請求的資源。
    以上這些功能,可以用很多方法來實現:
    • 在每個被訪問的資源中( JSP Servlet )中都加入身份認證的服務,來獲得 cookie ,并且判斷當前用戶是否登錄過。不過這個笨方法沒有人會用 :-)
    • 可以通過一個 controller ,將所有的功能都寫到一個 servlet 中,然后在 URL 映射的時候,映射到所有需要保護的 URL 集合中(例如 *.jsp /security/* 等)。這個方法可以使用,不過,它的缺點是不能重用。在每個應用中都要部署一個相同的 servlet
    • Filter 是比較好的方法。符合 Servlet2.3 以上的 J2EE 容器就具有部署 filter 的功能。( Filter 的使用可以參考 JavaWolrd 的文章 http://www.javaworld.com/javaworld/jw-06-2001/jw-0622-filters.html Filter 是一個具有很好的模塊化,可重用的編程 API ,用在 SSO 正合適不過。本樣例就是使用一個 filter 來完成以上的功能。
    ?
    package SSO;
    ?
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import java.text.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import javax.servlet.*;
    import org.apache.commons.httpclient.*;
    import org.apache.commons.httpclient.methods.GetMethod;
    ?
    public class SSOFilter implements Filter {
    ??? private FilterConfig filterConfig = null;
    ??? private String cookieName="WangYuDesktopSSOID";
    ??? private String SSOServiceURL=?"http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth";
    ??? private String SSOLoginPage= "http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp";
    ???
    ??? public void init(FilterConfig filterConfig) {
    ?
    ??????? this.filterConfig = filterConfig;
    ??????? if (filterConfig != null) {
    ??????????? if (debug) {
    ??????????????? log("SSOFilter:Initializing filter");
    ??????????? }
    ??????? }???????
    ??????? cookieName = filterConfig.getInitParameter("cookieName");
    ??????? SSOServiceURL = filterConfig.getInitParameter("SSOServiceURL");
    ??????? SSOLoginPage = filterConfig.getInitParameter("SSOLoginPage");
    ??? }?
    .....
    .....
    ?
    }
    以上的初始化的源代碼有兩點需要說明:一是有兩個需要配置的參數 SSOServiceURL SSOLoginPage 。因為當前的 Web 應用很可能和身份認證服務( SSOAuth )不在同一臺機器上,所以需要讓這個 filter 知道身份認證服務部署的 URL ,這樣才能去調用它的服務。另外一點就是由于身份認證的服務調用是要通過 http 協議來調用的(在本樣例中是這樣設計的,讀者完全可以設計自己的身份服務,使用別的調用協議,如 RMI SOAP 等等),所有筆者引用了 apache commons 工具包(詳細信息情訪問 apache 的網站 http://jakarta.apache.org/commons/index.html ),其中的 httpclient” 可以大大簡化 http 調用的編程。
    下面看看 filter 的主體方法 doFilter():
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    ??????? if (debug) log("SSOFilter:doFilter()");
    ??????? HttpServletRequest request = (HttpServletRequest) req;
    ??????? HttpServletResponse response = (HttpServletResponse) res;
    ??????? String result="failed";
    ??????? String url = request.getRequestURL().toString();
    ??????? String qstring = request.getQueryString();
    ??????? if (qstring == null) qstring ="";
    ?
    ??????? // 檢查 http 請求的 head 是否有需要的 cookie
    ??????? String cookieValue ="";
    ??????? javax.servlet.http.Cookie[] diskCookies = request.getCookies();
    ??????? if (diskCookies != null) {
    ??????????? for (int i = 0; i < diskCookies.length; i++) {
    ??????????????? if(diskCookies[i].getName().equals(cookieName)){
    ??????????????????? cookieValue = diskCookies[i].getValue();
    ?
    ??????????????????? // 如果找到了相應的 cookie 則效驗其有效性
    ??????????????????? result = SSOService(cookieValue);
    ??????????????????? if (debug) log("found cookies!");
    ???????? ??????? }
    ??????????? }
    ??????? }
    ??????? if (result.equals("failed")) { // 效驗失敗或沒有找到 cookie ,則需要登錄
    ??????????? response.sendRedirect(SSOLoginPage+"?goto="+url);
    ??????? } else if (qstring.indexOf("logout") > 1) {//logout 服務
    ??????????? if (debug) log("logout action!");
    ??????????? logoutService(cookieValue);
    ??????????? response.sendRedirect(SSOLoginPage+"?goto="+url);
    ??????? }?else {// 效驗成功
    ??????????? request.setAttribute("SSOUser",result);
    ??????????? Throwable problem = null;
    ??????????? try {
    ??????????? ???? chain.doFilter(req, res);
    ??????????? } catch(Throwable t) {
    ??????????????? problem = t;
    ??????????????? t.printStackTrace();
    ??????????? }??????
    ??????????? if (problem != null) {
    ??????????????? if (problem instanceof ServletException) throw (ServletException)problem;
    ??????????????? if (problem instanceof IOException) throw (IOException)problem;
    ??????????????? sendProcessingError(problem, res);
    ??????????? }
    ??????? }??
    ??? }
    doFilter() 方法的邏輯也是非常簡單的,在接收到請求的時候,先去查找是否存在期望的 cookie 值,如果找到了,就會調用 SSOService(cookieValue) 去效驗這個 cookie 的有效性。如果 cookie 效驗不成功或者 cookie 根本不存在,就會直接轉到登錄界面讓用戶登錄;如果 cookie 效驗成功,就不會做任何阻攔,讓此請求進行下去。在配置文件中,有下面的一個節點表示了此 filter URL 映射關系:只攔截所有的 jsp 請求。
    <filter-mapping>
    <filter-name>SSOFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    ?
    下面還有幾個主要的函數需要說明:
    ??? private String SSOService(String cookievalue) throws IOException {
    ??????? String authAction = "?action=authcookie&cookiename=";
    ??????? HttpClient httpclient = new HttpClient();
    ??????? GetMethod httpget = new GetMethod(SSOServiceURL+authAction+cookievalue);
    ??????? try {?
    ??????????? httpclient.executeMethod(httpget);
    ??????????? String result = httpget.getResponseBodyAsString();
    ??????????? return result;
    ??????? } finally {
    ??????????? httpget.releaseConnection();
    ??????? }
    ??? }
    ???
    ??? private void logoutService(String cookievalue) throws IOException {
    ??????? String authAction = "?action=logout&cookiename=";
    ??????? HttpClient httpclient = new HttpClient();
    ??????? GetMethod httpget = new GetMethod(SSOServiceURL+authAction+cookievalue);
    ??????? try {
    ??????????? httpclient.executeMethod(httpget);
    ??????????? httpget.getResponseBodyAsString();
    ??????? } finally {
    ??????????? httpget.releaseConnection();
    ??????? }
    ??? }
    這兩個函數主要是利用 apache 中的 httpclient 訪問 SSOAuth 提供的認證服務來完成效驗 cookie logout 的功能。
    其他的函數都很簡單,有很多都是我的 IDE NetBeans )替我自動生成的。
    4 當前方案的安全局限性
    當前這個 WEB-SSO 的方案是一個比較簡單的雛形,主要是用來演示 SSO 的概念和說明 SSO 技術的實現方式。有很多方面還需要完善,其中安全性是非常重要的一個方面。
    我們說過,采用 SSO 技術的主要目的之一就是加強安全性,降低安全風險。因為采用了 SSO ,在網絡上傳遞密碼的次數減少,風險降低是顯然的,但是當前的方案卻有其他的安全風險。由于 cookie 是一個用戶登錄的唯一憑據,對 cookie 的保護措施是系統安全的重要環節:
    • cookie 的長度和復雜度
      在本方案中, cookie 是有一個固定的字符串(我的姓名)加上當前的時間戳。這樣的 cookie 很容易被偽造和猜測。懷有惡意的用戶如果猜測到合法的 cookie 就可以被當作已經登錄的用戶,任意訪問權限范圍內的資源
    • cookie 的效驗和保護
      在本方案中,雖然密碼只要傳輸一次就夠了,可 cookie 在網絡中是經常傳來傳去。一些網絡探測工具(如 sniff, snoop,tcpdump 等)可以很容易捕獲到 cookie 的數值。在本方案中,并沒有考慮 cookie 在傳輸時候的保護。另外對 cookie 的效驗也過于簡單,并不去檢查發送 cookie 的來源究竟是不是 cookie 最初的擁有者,也就是說無法區分正常的用戶和仿造 cookie 的用戶。
    • 當其中一個應用的安全性不好,其他所有的應用都會受到安全威脅
      因為有 SSO ,所以當某個處于 SSO 的應用被黒客攻破,那么很容易攻破其他處于同一個 SSO 保護的應用。
    這些安全漏洞在商業的 SSO 解決方案中都會有所考慮,提供相關的安全措施和保護手段,例如 Sun 公司的 Access Manager cookie 的復雜讀和對 cookie 的保護都做得非常好。另外在 OpneSSO https://opensso.dev.java.net/ )的架構指南中也給出了部分安全措施的解決方案。
    5 當前方案的功能和性能局限性
    除了安全性,當前方案在功能和性能上都需要很多的改進:
    • 當前所提供的登錄認證模式只有一種:用戶名和密碼,而且為了簡單,將用戶名和密碼放在內存當中。事實上,用戶身份信息的來源應該是多種多樣的,可以是來自數據庫中, LDAP 中,甚至于來自操作系統自身的用戶列表。還有很多其他的認證模式都是商務應用不可缺少的,因此 SSO 的解決方案應該包括各種認證的模式,包括數字證書, Radius SafeWord MemberShip SecurID 等多種方式。最為靈活的方式應該允許可插入的 JAAS 框架來擴展身份認證的接口
    • 我們編寫的 Filter 只能用于 J2EE 的應用,而對于大量非 Java Web 應用,卻無法提供 SSO 服務。
    • 在將 Filter 應用到 Web 應用的時候,需要對容器上的每一個應用都要做相應的修改,重新部署。而更加流行的做法是 Agent 機制:為每一個應用服務器安裝一個 agent ,就可以將 SSO 功能應用到這個應用服務器中的所有應用。
    • 當前的方案不能支持分別位于不同 domain Web 應用進行 SSO 。這是因為瀏覽器在訪問 Web 服務器的時候,僅僅會帶上和當前 web 服務器具有相同 domain 名稱的那些 cookie 。要提供跨域的 SSO 的解決方案有很多其他的方法,在這里就不多說了。 Sun Access Manager 就具有跨域的 SSO 的功能。
    • 另外, Filter 的性能問題也是需要重視的方面。因為 Filter 會截獲每一個符合 URL 映射規則的請求,獲得 cookie ,驗證其有效性。這一系列任務是比較消耗資源的,特別是驗證 cookie 有效性是一個遠程的 http 的調用,來訪問 SSOAuth 的認證服務,有一定的延時。因此在性能上需要做進一步的提高。例如在本樣例中,如果將 URL 映射從“ .jsp 改成“ /* ,也就是說 filter 對所有的請求都起作用,整個應用會變得非常慢。這是因為,頁面當中包含了各種靜態元素如 gif 圖片, css 樣式文件,和其他 html 靜態頁面,這些頁面的訪問都要通過 filter 去驗證。而事實上,這些靜態元素沒有什么安全上的需求,應該在 filter 中進行判斷,不去效驗這些請求,性能會好很多。另外,如果在 filter 中加上一定的 cache ,而不需要每一個 cookie 效驗請求都去遠端的身份認證服務中執行,性能也能大幅度提高。
    • 另外系統還需要很多其他的服務,如在內存中定時刪除無用的 cookie 映射等等,都是一個嚴肅的解決方案需要考慮的問題。
    6 桌面 SSO 的實現
    WEB-SSO 的概念延伸開,我們可以把 SSO 的技術拓展到整個桌面的應用,不僅僅局限在瀏覽器。 SSO 的概念和原則都沒有改變,只需要再做一點點的工作,就可以完成桌面 SSO 的應用。
    桌面 SSO WEB-SSO 一樣,關鍵的技術也在于如何在用戶登錄過后保存登錄的憑據。在 WEB-SSO 中,登錄的憑據是靠瀏覽器的 cookie 機制來完成的;在桌面應用中,可以將登錄的憑證保存到任何地方,只要所有 SSO 的桌面應用都共享這個憑證。
    從網站可以下載一個簡單的桌面 SSO 的樣例 (http://gceclub.sun.com.cn/wangyu/ 和全部源碼( http://gceclub.sun.com.cn/wangyu/desktop-sso/desktopsso_src.zip ),雖然簡單,但是它具有桌面 SSO 大多數的功能,稍微加以擴充就可以成為自己的解決方案。
    ?
    6.1 桌面樣例的部署
    1. 運行此桌面 SSO 需要三個前提條件:
      a) WEB-SSO
      的身份認證應用應該正在運行,因為我們在桌面 SSO 當中需要用到統一的認證服務
      b)
      當前桌面需要運行 Mozilla Netscape 瀏覽器,因為我們將 ticket 保存到 mozilla cookie 文件中
      c)
      必須在 JDK1.4 以上運行。( WEB-SSO 需要 JDK1.5 以上)
    2. 解開 desktopsso.zip 文件,里面有兩個目錄 bin lib
    3. bin 目錄下有一些腳本文件和配置文件,其中 config.properties 包含了三個需要配置的參數:
      a) SSOServiceURL
      要指向 WebSSO 部署的身份認證的 URL
      b) SSOLoginPage
      要指向 WebSSO 部署的身份認證的登錄頁面 URL
      c) cookiefilepath
      要指向當前用戶的 mozilla 所存放 cookie 的文件
    4. bin 目錄下還有一個 login.conf 是用來配置 JAAS 登錄模塊,本樣例提供了兩個,讀者可以任意選擇其中一個(也可以都選),再重新運行程序,查看登錄認證的變化
    5. bin 下的運行腳本可能需要作相應的修改
      a)
      如果是在 unix 下,各個 jar 文件需要用“ : 來隔開,而不是“ ;
      b) java
      運行程序需要放置在當前運行的路徑下,否則需要加上 java 的路徑全名。
    ?
    6.2 桌面樣例的運行
    樣例程序包含三個簡單的 Java 控制臺程序,這三個程序單獨運行都需要登錄。如果運行第一個命叫“ GameSystem 的程序,提示需要輸入用戶名和密碼:
    效驗成功以后,便會顯示當前登錄的用戶的基本信息等等。
    ?
    這時候再運行第二個桌面 Java 應用( mailSystem )的時候,就不需要再登錄了,直接就顯示出來剛才登錄的用戶。
    第三個應用是 logout ,運行它之后,用戶便退出系統。再訪問的時候,又需要重新登錄了。請讀者再制裁執行完 logout 之后,重新驗證一下前兩個應用的 SSO :先運行第二個應用,再運行第一個,會看到相同的效果。
    我們的樣例并沒有在這里停步,事實上,本樣例不僅能夠和在幾個 Java 應用之間 SSO ,還能和瀏覽器進行 SSO ,也就是將瀏覽器也當成是桌面的一部分。這對一些行業有著不小的吸引力。
    這時候再打開 Mozilla 瀏覽器,訪問以前提到的那兩個 WEB 應用,會發現只要桌面應用如果登錄過, Web 應用就不用再登錄了,而且能顯示剛才登錄的用戶的信息。讀者可以在幾個桌面和 Web 應用之間進行登錄和 logout 的試驗,看看它們之間的 SSO
    6.3 桌面樣例的源碼分析
    桌面 SSO 的樣例使用了 JAAS (要了解 JAAS 的詳細的信息請參考 http://java.sun.com/products/jaas )。 JAAS 是對 PAM Pluggable Authentication Module )的 Java 實現,來完成 Java 應用可插拔的安全認證模塊。使用 JAAS 作為 Java 應用的安全認證模塊有很多好處,最主要的是不需要修改源代碼就可以更換認證方式。例如原有的 Java 應用如果使用 JAAS 的認證,如果需要應用 SSO ,只需要修改 JAAS 的配置文件就行了。現在在流行的 J2EE 和其他 Java 的產品中,用戶的身份認證都是通過 JAAS 來完成的。在樣例中,我們就展示了這個功能。請看配置文件 login.conf
    ??? DesktopSSO {
    ?? desktopsso.share.PasswordLoginModule required;
    ?? desktopsso.share.DesktopSSOLoginModule required;
    };
    當我們注解掉第二個模塊的時候,只有第一個模塊起作用。在這個模塊的作用下,只有 test 用戶(密碼是 12345 )才能登錄。當我們注解掉第一個模塊的時候,只有第二個模塊起作用,桌面 SSO 才會起作用。
    ?
    所有的 Java 桌面樣例程序都是標準 JAAS 應用,熟悉 JAAS 的程序員會很快了解。 JAAS 中主要的是登錄模塊( LoginModule )。下面是 SSO 登錄模塊的源碼:
    ? public class DesktopSSOLoginModule implements LoginModule {
    ?? ..........
    ?? private String SSOServiceURL = "";
    ?? private String SSOLoginPage = "";
    ?? private static String cookiefilepath = "";??
    ?? .........
    ?
    config.properties 的文件中,我們配置了它們的值:
    SSOServiceURL=http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth
    SSOLoginPage=http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp
    cookiefilepath=C:\\Documents and Settings\\yw137672\\Application Data\\Mozilla\\Profiles\\default\\hog6z1ji.slt\\cookies.txt
    SSOServiceURL SSOLoginPage 成員變量指向了在 Web-SSO 中用過的身份認證模塊: SSOAuth ,這就說明在桌面系統中我們試圖和 Web 應用共用一個認證服務。而 cookiefilepath 成員變量則泄露了一個“天機”:我們使用了 Mozilla 瀏覽器的 cookie 文件來保存登錄的憑證。換句話說,和 Mozilla 共用了一個保存登錄憑證的機制。之所以用 Mozilla 是應為它的 Cookie 文件格式簡單,很容易編程訪問和修改任意的 Cookie 值。(我試圖解析 Internet Explorer cookie 文件但沒有成功。)
    下面是登錄模塊DesktopSSOLoginModule的主體: login() 方法。邏輯也是非常簡單:先用 Cookie 來登陸,如果成功,則直接就進入系統,否則需要用戶輸入用戶名和密碼來登錄系統。
    ??? public boolean login() throws LoginException{
    ??????? try {
    ??????????? if (Cookielogin()) return true;
    ??????? } catch (IOException ex) {
    ??????????? ex.printStackTrace();
    ??????? }
    ????? if (passwordlogin()) return true;
    ????? throw new FailedLoginException();
    ? }
    ?
    下面是Cookielogin() 方法的實體,它的邏輯是: 先從 Cookie 文件中獲得相應的 Cookie 值,通過身份效驗服務效驗 Cookie 的有效性。如果 cookie 有效 就算登錄成功;如果不成功或 Cookie 不存在,用 cookie 登錄就算失敗。
    ??? public boolean Cookielogin() throws LoginException,IOException {
    ????? String?cookieValue="";
    ????? int cookieIndex =foundCookie();
    ????? if (cookieIndex<0)
    ??????????? return false;
    ????? else
    ??????????? cookieValue = getCookieValue(cookieIndex);
    ???? username = cookieAuth(cookieValue);
    ???? if (! username.equals("failed")) {
    ???????? loginSuccess =?true;
    ???????? return true;
    ???? }
    ???? return false;
    ? }
    ?
    ?
    用用戶名和密碼登錄的方法要復雜一些,通過 Callback 的機制和屏幕輸入輸出進行信息交互,完成用戶登錄信息的獲取;獲取信息以后通過 userAuth 方法來調用遠端 SSOAuth 的服務來判定當前登錄的有效性。
    ?? public boolean passwordlogin() throws LoginException {
    ??? //
    ??? // Since we need input from a user, we need a callback handler
    ??? if (callbackHandler == null) {
    ?????? throw new LoginException("No CallbackHandler defined");
    ??? }
    ??? Callback[] callbacks = new Callback[2];
    ??? callbacks[0] = new NameCallback("Username");
    ??? callbacks[1] = new PasswordCallback("Password", false);
    ??? //
    ??? // Call the callback handler to get the username and password
    ??? try {
    ????? callbackHandler.handle(callbacks);
    ????? username = ((NameCallback)callbacks[0]).getName();
    ????? char[] temp = ((PasswordCallback)callbacks[1]).getPassword();
    ????? password = new char[temp.length];
    ????? System.arraycopy(temp, 0, password, 0, temp.length);
    ????? ((PasswordCallback)callbacks[1]).clearPassword();
    ??? } catch (IOException ioe) {
    ????? throw new LoginException(ioe.toString());
    ??? } catch (UnsupportedCallbackException uce) {
    ????? throw new LoginException(uce.toString());
    ??? }
    ???
    ??? System.out.println();
    ??? String authresult ="";
    ??? try {
    ??????? authresult = userAuth(username, password);
    ??? } catch (IOException ex) {
    ??????? ex.printStackTrace();
    ??? }
    ??? if (! authresult.equals("failed")) {
    ??????? loginSuccess= true;
    ??????? clearPassword();
    ??????? try {
    ??????????? updateCookie(authresult);
    ??????? } catch (IOException ex) {
    ??????????? ex.printStackTrace();
    ??????? }
    ??????? return true;
    ??? }
    ??
    ?
    ??? loginSuccess = false;
    ??? username = null;
    ??? clearPassword();
    ??? System.out.println( "Login: PasswordLoginModule FAIL" );
    ??? throw new FailedLoginException();
    ? }
    ?
    ?
    CookieAuth userAuth 方法都是利用 apahce httpclient 工具包和遠程的 SSOAuth 進行 http 連接,獲取服務。
    ??????? private String cookieAuth(String cookievalue) throws IOException{
    ??????? String result = "failed";
    ???????
    ??????? HttpClient httpclient = new HttpClient();??????
    ??????? GetMethod httpget = new GetMethod(SSOServiceURL+Action1+cookievalue);
    ???
    ??????? try {
    ??????????? httpclient.executeMethod(httpget);
    ??????????? result = httpget.getResponseBodyAsString();
    ??????? } finally {
    ??????????? httpget.releaseConnection();
    ??????? }
    ??????? return result;
    ??? }
    ?
    private String userAuth(String username, char[] password) throws IOException{
    ??????? String result = "failed";
    ??????? String passwd= new String(password);
    ??????? HttpClient httpclient = new HttpClient();??????
    ??????? GetMethod httpget = new GetMethod(SSOServiceURL+Action2+username+"&password="+passwd);
    ??????? passwd = null;
    ???
    ??????? try {
    ??????????? httpclient.executeMethod(httpget);
    ??????????? result = httpget.getResponseBodyAsString();
    ??????? } finally {
    ??????????? httpget.releaseConnection();
    ??????? }
    ??????? return result;
    ???????
    ??? }
    ?
    還有一個地方需要補充說明的是,在本樣例中,用戶名和密碼的輸入都會在屏幕上顯示明文。如果希望用掩碼形式來顯示密碼,以提高安全性,請參考: http://java.sun.com/developer/technicalArticles/Security/pwordmask/
    7 真正安全的全方位 SSO 解決方案: Kerberos
    我們的樣例程序(桌面 SSO WEB-SSO )都有一個共性:要想將一個應用集成到我們的 SSO 解決方案中,或多或少的需要修改應用程序。 Web 應用需要配置一個我們預制的 filter ;桌面應用需要加上我們桌面 SSO JAAS 模塊(至少要修改 JAAS 的配置文件)。可是有很多程序是沒有源代碼和無法修改的,例如常用的遠程通訊程序 telnet ftp 等等一些操作系統自己帶的常用的應用程序。這些程序是很難修改加入到我們的 SSO 的解決方案中。
    事實上有一種全方位的 SSO 解決方案能夠解決這些問題,這就是 Kerberos 協議( RFC 1510 )。 Kerberos 是網絡安全應用標準 (http://web.mit.edu/kerberos/) ,由 MIT 學校發明,被主流的操作系統所采用。在采用 kerberos 的平臺中,登錄和認證是由操作系統本身來維護,認證的憑證也由操作系統來保存,這樣整個桌面都可以處于同一個 SSO 的系統保護中。操作系統中的各個應用(如 ftp,telnet )只需要通過配置就能加入到 SSO 中。另外使用 Kerberos 最大的好處在于它的安全性。通過密鑰算法的保證和密鑰中心的建立,可以做到用戶的密碼根本不需要在網絡中傳輸,而傳輸的信息也會十分的安全。
    目前支持 Kerberos 的操作系統包括 Solaris, windows,Linux 等等主流的平臺。只不過要搭建一個 Kerberos 的環境比較復雜, KDC (密鑰分發中心)的建立也需要相當的步驟。 Kerberos 擁有非常成熟的 API ,包括 Java API 。使用 Java Generic Security Services(GSS) API 并且使用 JAAS 中對 Kerberos 的支持(詳細信息請參見 Sun Java&Kerberos 教程 http://java.sun.com/ j2se/1.5.0/docs/guide/security/jgss/tutorials/index.html ),要將我們這個樣例改造成對 Kerberos 的支持也是不難的。 值得一提的是在 JDK6.0 http://www.java.net/download/jdk6 )當中直接就包含了對 GSS 的支持,不需要單獨下載 GSS 的包。
    ?
    8 總結
    本文的主要目的是闡述 SSO 的基本原理,并提供了一種實現的方式。通過對源代碼的分析來掌握開發 SSO 服務的技術要點和充分理解 SSO 的應用范圍。但是,本文僅僅說明了身份認證的服務,而另外一個和身份認證密不可分的服務 ---- 權限效驗,卻沒有提到。要開發出真正的 SSO 的產品,在功能上、性能上和安全上都必須有更加完備的考慮。
    作者簡介
    王昱是 Sun 中國工程研究院的 Java 工程師,現在的主要負責全球合作伙伴的技術支持。作為一名 Java 資深工程師和架構師,王昱在 Java 的很多領域都有多年的造詣,特別是在 Java 虛擬機、 J2EE 技術 ( 包括 EJB, JSP/Servlet, JMS Web services 等技術 ) 、集群技術和 Java 應用性能調優上有著較為豐富的經驗。曾經多次在重要的 Java 會議發表演講,并在國際著名的 Java 技術站 點發表文章。
    ?
    資源鏈接


    jwebee

    我的個人網站
    posted on 2007-03-08 16:14 周行 閱讀(3836) 評論(1)  編輯  收藏 所屬分類: IT技術

    FeedBack:
    # re: 單點登陸(Single Sign-On,SSO)
    2011-08-09 19:42 | 盧寶林
    下載鏈接好像不能用,可否給發一份

    lubaolin@powerec.net  回復  更多評論
      
    Java-Android-jwebee
    主站蜘蛛池模板: 91精品视频免费| 色婷婷六月亚洲综合香蕉| 国产一级淫片a免费播放口之| 无码AV片在线观看免费| 无遮挡国产高潮视频免费观看| 亚洲精品免费网站| 内射干少妇亚洲69XXX| 久久久久亚洲精品天堂久久久久久| 成人免费午夜视频| 国产91色综合久久免费分享| 国产免费爽爽视频在线观看 | 亚洲三级在线免费观看| 两个人看的www免费视频| 最好2018中文免费视频| 国产亚洲欧美在线观看| 亚洲精品宾馆在线精品酒店| 亚洲综合久久一本伊伊区| 亚洲色偷偷偷网站色偷一区| 亚洲免费视频在线观看| 亚洲国产精品乱码一区二区| 国产亚洲精品高清在线| 亚洲中文字幕久久精品无码APP | 亚洲导航深夜福利| 噜噜噜亚洲色成人网站∨| 亚洲免费在线播放| 亚洲大香伊人蕉在人依线| 亚洲福利电影在线观看| 久久久久久久亚洲Av无码 | 99久久精品免费视频| 三年片在线观看免费观看大全一| 3344在线看片免费| 国产三级在线免费| 日韩精品无码专区免费播放| 老汉精品免费AV在线播放| 91福利视频免费| AV大片在线无码永久免费| 无人影院手机版在线观看免费| 免费电视剧在线观看| 青青草国产免费久久久下载| 国产成人免费手机在线观看视频| 四虎影院永久免费观看|