1. 程式人生 > >跨域單點登入實現

跨域單點登入實現

       本文來自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/20545513,轉載請註明。
       完全跨域的單點登入實現方案基本和上篇文章介紹的一樣,只不過生成ticket的過程更復雜些。上篇文章中的專案是不能完全跨域的,由於多個應用系統以及認證系統域不同,也沒有共同的父域,導致登入後,認證系統向瀏覽器寫的ticket在其它應用系統中獲取不到,這時訪問其它應用系統時,沒有攜帶著ticket的cookie,無法認證也無法單點登入。那解決的方案是每個應用系統都向瀏覽器cookie中寫入ticket,請看下圖,圖中淺藍色圓角區域代表不同的域,當用戶通過瀏覽器第一次訪問應用系統1時,由於還沒有登入,會被引導到認證系統進行登入。下面開始單點登入的過程:認證系統根據使用者在瀏覽器中輸入的登入資訊,進行身份認證,如果認證通過,返回給瀏覽器一個證明[認證系統_ticket];這時再通過瀏覽器將[認證系統_ticket]傳送到到應用系統1的設定cookie的url,應用系統1返回給瀏覽器一個證明[應用系統1_ticket],這時再將請求重定向到最初訪問的頁面,以後應用系統1就可以自動登入了。現在使用者訪問了應用系統2,由於應用系統2沒有生成過cookie(但是使用者已經在應用系統1登入過一次了),將請求重定向到認證系統;認證系統檢測到已經生成過[認證系統_ticket]了,認證通過;再通過瀏覽器將[認證系統_ticket]傳送到到應用系統2的設定cookie的url,應用系統2返回給瀏覽器一個證明[應用系統2_ticket],這時再將請求重定向到最初訪問的頁面。應用系統3也同樣原理,我們等於將ticket做了一次同步,保證了每個應用系統都有一份認證系統產生的ticket。剩餘的ticket驗證過程和上篇文章一樣了。

       ticket同步的過程用jsonp應該也可以實現,我基於上篇文章中的專案實現了完全跨域的單點登入,可以在這裡下載專案。

域名準備

修改hosts檔案,對映3個域名:

[html] view plain copy  print?
  1. 127.0.0.1 web1.com  
  2. 127.0.0.1 web2.com  
  3. 127.0.0.1 passport.com  
       三個域名都是獨立的,沒有共同父域,web1和web2用於訪問應用系統,passport用於訪問認證系統。

專案部署

專案中包含的是兩個Eclipse Project,匯入到Eclipse/MyEclipse後,可能需要設定下JavaEE類庫。WebSSOAuth為認證系統,WebSSODemo為應用系統,如果對映的域名和我設定的一樣,不需要設定,直接部署即可。如果不一樣,需要修改下WebSSODemo/WEB-INF/web.xml檔案。關鍵配置資訊如下:

[html] view plain copy  print?
  1. <filter>
  2.     <filter-name>SSOAuth</filter-name>
  3.     <filter-class>com.ghsau.filter.SSOAuth</filter-class>
  4.     <init-param>
  5.         <!-- 認證系統服務 -->
  6.         <param-name>SSOService</param-name>
  7.         <param-value
    >http://passport.com:8080/WebSSOAuth/SSOAuth</param-value>
  8.     </init-param>
  9.     <init-param>
  10.         <!-- 認證系統ticket名稱 -->
  11.         <param-name>cookieName</param-name>
  12.         <param-value>SSOID</param-value>
  13.     </init-param>
  14. </filter>
  15. <filter-mapping>
  16.     <filter-name>SSOAuth</filter-name>
  17.     <url-pattern>*.jsp</url-pattern>
  18. </filter-mapping>
  19. <filter-mapping>
  20.     <filter-name>SSOAuth</filter-name>
  21.     <url-pattern>/logout</url-pattern>
  22. </filter-mapping>
  23. <filter-mapping>
  24.     <filter-name>SSOAuth</filter-name>
  25.     <url-pattern>/setCookie</url-pattern>
  26. </filter-mapping>
       如果域名或埠號和我的不一致,可以修改對應配置項。最後部署到應用伺服器中,啟動伺服器。

SSO使用

       首先輸入第一個應用系統的訪問地址,http://web1.com:8080/WebSSODemo/index.jsp,如果是第一次訪問的話,會自動跳轉到登入頁,如下圖:

       系統中內建了3個使用者,張三、李四、王五,使用者名稱和密碼皆為拼音全拼,輸入zhangsan/zhangsan登入後,會自動跳轉到我們剛才訪問的頁面,頁面中顯示了登入的使用者名稱及歡迎資訊,如下圖:

       這時,我們再輸入第二個應用系統的訪問地址,http://web2.com:8080/WebSSODemo/index.jsp,我們發現,沒有進行第二次登入,同樣頁面中顯示了登入的使用者名稱及歡迎資訊,如下圖:

       我們接著點選Logout登出使用者,頁面跳轉到了登入頁面,這時我們再回頭訪問第一個應用系統的頁面,發現同樣跳轉到了登入頁面。
       網際網路中的完全跨域登入的站點也有很多,如淘寶天貓,但肯定不是我這樣實現的。我的實現中,認證系統和應用系統是通過url引數來傳遞ticket,可能存在一些不穩定因素。應用系統的每次請求都會通過HTTP遠端到認證系統進行驗證ticket,速度上應該會慢一些,這裡可以改進一步,在每個應用系統中也維護一份tickets,驗證時,首先到本系統中驗證,如果不存在,再遠端到認證系統進行驗證,但這也增加了應用系統的程式碼量。本文完,如果有什麼問題,歡迎討論。
       本文來自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/20545513,轉載請註明。