1.若是兩個網站域名的一級域名相同,可使用cookie和filter實現單點登陸,由於網站有可能(具體看cookie的設置)能夠共享cookie。例如:www.bbs.aa.cn www.news.aa.cn。javascript
第一個網站在登陸後,把用戶信息寫到cookie中,當訪問第二個網站時,第二個網站先通過本身的filter,檢查session,若是沒有,查詢cookie,取出用戶信息,放在session中登陸。php
\html
1其實單點登陸很簡單前端
單點登陸的技術實現機制:當用戶第一次訪問應用系統1的時候,由於尚未登陸,會被引導到認證系統中進行登陸;根據用戶提供的登陸信息,認證系統進行身份效驗,若是經過效驗,應該返回給用戶一個認證的憑據--ticket;用戶再訪問別的應用的時候,就會將這個ticket帶上,做爲本身認證的憑據,應用系統接受到請求以後會把ticket送到認證系統進行效驗,檢查ticket的合法性。若是經過效驗,用戶就能夠在不用再次登陸的狀況下訪問應用系統2和應用系統3了。java
能夠看出,要實現SSO,須要如下主要的功能:web
a) 全部應用系統共享一個身份認證系統;apache
b) 全部應用系統可以識別和提取ticket信息;json
c) 應用系統可以識別已經登陸過的用戶,能自動判斷當前用戶是否登陸過,從而完成單點登陸的功能windows
基於以上基本原則,本人用php語言設計了一套單點登陸系統的程序,目前已投入正式生成服務器運行。本系統程序,將ticket信息以全系統惟一的 session id做爲媒介,從而獲取當前在線用戶的全站信息(登錄狀態信息及其餘須要處理的用戶全站信息)。後端
二. 過程說明:
登錄流程:
1. 第一次登錄某個站:
a) 用戶輸入用戶名+密碼,向用戶驗證中心發送登陸請求
b) 當前登陸站點,經過webservice請求,用戶驗證中心驗證用戶名,密碼的合法性。若是驗證經過,則生成ticket,用於標識當前會話的用戶,並將當前登錄子站的站點標識符記錄到用戶中心,最後
c) 將獲取的用戶數據和ticket返回給子站。若是驗證不經過,則返回相應的錯誤狀態碼。
d) 根據上一步的webservice請求返回的結果,當前子站對用戶進行登錄處理:如狀態碼錶示成功的話,則當前站點經過本站cookie保存ticket,並本站記錄用戶的登陸狀態。狀態碼錶示失敗的話,則給用戶相應的登陸失敗提示。
2. 登錄狀態下,用戶轉到另外一子:
a) 經過本站cookie或session驗證用戶的登陸狀態:如驗證經過,進入正常本站處理程序;不然戶中心驗證用戶的登陸狀態(發送ticket到用戶驗證中心),如驗證經過,則對返回的用戶信息進行本地的登陸處理,不然代表用戶未登陸。
登出流程
a) 當前登出站清除用戶本站的登陸狀態 和 本地保存的用戶全站惟一的隨機id
b) 經過webservice接口,清除全站記錄的全站惟一的隨機id。webservice接口會返回,登出其餘已登陸子站的javascript代碼,本站輸出此代碼。
c) js代碼訪問相應站W3C標準的登出腳本
WEB的登陸那些事
說道帳戶登陸和註冊,其實咱們天天都在親身感覺着,像微博、知乎還有簡書等等。咱們老是須要按期的去從新登陸一下,對於這種認證機制,咱們都能說出來兩個名詞,Cookie、Session。的確沒錯,Cookie和Session是實現這一切的核心。
爲何會有Cookie和Session?區別是什麼?
引入這兩個概念的根本緣由是由於Http協議是無狀態的,也就是說它不能創建起屢次請求之間的關係。因此須要引入一個能有瀏覽器或服務器保存的一個上下文狀態,也就是Cookie和Session。說到底Session的實現是依賴於Cookie的,由於Cookie是真正的由瀏覽器保存的狀態,Session是利用了JSessionID。在我看來其實二者有差別,可是根本的依賴是同樣的。Cookie也是有生命週期的,像Session級別或者有必定「壽命」的Cookie。一切是由瀏覽器去維護的。
常見的跨域登陸問題
以前樓主主要是作帳戶和Passport這方面的工做,其實在跨域這也是遇見了一些問題。
對於同一個根域下的登陸問題
若是咱們的站點有不止一個業務,那麼他們可能部署在不一樣的機器上,也每每須要不一樣的域名進行區分。可是全部的業務又都是依賴於一套帳戶體系,那麼咱們這時候須要經過一次登陸解決全部站點的登陸問題,那麼咱們這個時候可使用一個最笨的方法:那就是一次登陸成功,將Cookie寫到根域下,那麼這樣全部的站點就能實現,同一個根域下的Cookie共享,天然實現了」單點登陸「。
對於多個根域下的登陸問題
若是是多個根域名,那麼這種狀況下上面的機制就不能實現「單點登陸」了。由於之因此上面能夠實現「單點登陸」的效果。是由於瀏覽器和Http協議的支持。可是對於跨根域的站點之間進行Cookie的共享是比較複雜的。
方法1:登陸成功以後將Cookie回寫到多個域名下。
這種辦法可能十分簡單,你能夠經過後端的response寫修改的是響應頭信息 ,也能夠用前端js去寫,可是必須有對全部須要「單點登陸」的站點進行逐一的寫入。用腳想這種辦法也是行不通的,由於你須要維護一個站點的列表,維護工做十分複雜,同時對於增長站點也會特別痛苦。對於Cookie的銷燬也是十分複雜的,由於仍是要對全部域名下的Cookie進行刪除。也就是說將原來須要作的工做增長了n倍。對於小型站點這種辦法是可取的。
方法2:jsonp
搞過前端的可能都知道用jsonp能夠作跨域的請求,而咱們解決的就是多個域下的統一登陸的問題,好像很瓜熟蒂落的樣子。可是,登陸是Server端作的吧?咱們在Client端作跨域的處理,這怎麼看也不是很合理。同時這種辦法須要很大的維護成本,每一次請求都要去固定的域下取相應的Cookie以後再作請求。想一想維護有頭疼。
方法3 :引入一箇中間態的Server
這種辦法算是一個簡化版的SSO,實現思想也十分的「狡猾」。可是對於小網站作跨域登陸的處理卻十分的有用,具體思路以下:
首先,咱們有兩個域名要實現單點登陸,同時咱們須要一箇中間的Server。
咱們有一個系統域名爲javahelp.com.cn,當咱們登陸的時候訪問javahelp.com.cn/wp-login進行登陸,登陸成功以後將Cookie回寫到javahelp這個域名下。
咱們還有一個系統域名爲javaWeb.com,當咱們訪問inside-javaWeb的時候,咱們沒有Cookie,那麼請求跳轉到中間系統jump。此時須要將當前域名帶到參數中便於jump校驗。這個jump系統是在javahelp域下的即:jump.javahelp.net。這時候就能拿到以前寫在javahelp域下的Cookie。
jump系統在收到了xulingbo域下的Cookie以後,取出xulingbo域下的Cookie,並redirect請求jump.inside-javaWeb.net,這個接口也是在jump系統中,請求後jump系統將Cookie回寫到inside-javaWeb域名下,這樣就實現了簡易的單點登陸。以下圖所示:
Paste_Image.png
可是這種方式不是很靈活,對於數據傳輸的安全性沒有保障,而且在銷燬Cookie的時候無能爲力,只能所有遍歷的銷燬。
方法4:基於CAS的SSO系統
CAS可不是java中的Compare-And-Swap,它是一個開源的單點登陸系統(SSO)。實現的機制不算複雜可是思想十分靈巧。用CAS也能夠快速實現單點登陸。盜圖一張說明sso單個域的登陸和驗證流程:
Paste_Image.png
CAS主要分爲CAS Client 和CAS Server ,其中Client主要是內嵌在須要SSO登陸站點的攔截器或過濾器上。
首先瀏覽器向站點1發起請求。
站點1發現當前請求沒有合法的Cookie,那麼重定向到CAS Server上,也就是SSO Server。
CAS Server展現登陸界面,要求用戶登陸。
用戶登陸後,會寫CAS Server的Cookie到瀏覽器,同時生產ticket,利用一個302跳轉到CASClient。這樣能保證用戶無感知。
CAS Client利用生成的ticket發送到CAS Server進行驗證,驗證經過後,站點1生成本身的Cookie並回寫到用戶瀏覽器,而後進行登陸成功的跳轉。
這樣就能保證當前瀏覽器在站點1的域名下,有站點1的Cookie,同時當前瀏覽器也有CAS Server的Cookie。
接下來看下站點2的登陸:
Paste_Image.png
站點2,在進行登陸時和站點1初次登陸流程一致,可是在訪問CAS Server的時候,因爲當前瀏覽器已經有了CAS Server的Cookie,那麼直接校驗經過返回ticket。
ticket經過302跳轉跳轉到CAS Client上,以後的流程就和站點1是同樣的了。若是此時認證失敗,那麼須要從新走一次登陸的過程。
其實感受很麻煩,可是流程卻十分的簡單,主要是使用CAS Server的Cookie作校驗,同時各自系統維護本身的Cookie。
注意的問題:
CAS Server的Cookie劫持問題,若是CAS Server的Cookie被劫持掉,那麼就至關於拿到了一切,因此必需要用HTTPS實現這個過程。
ticket的使用,ticket只能被使用一次,一次校驗後當即失效。同時須要有時效性,通常5分鐘。最後ticket生成規則要隨機,不能被碰撞出來。
對於各自系統本身的Session,也能夠依賴於SSO,這樣就能保證全部的Session規則一致,便於集中控制。
其實SSO的實現很靈活,CAS只是說了一個原理,至於具體怎麼實現,須要平衡安全性、易用性等諸多因素,因此也沒有一個固定的實現方案。
SSO之CAS單點登陸實例演示
1、概述
此文的目的就是爲了幫助初步接觸SSO和CAS 的人員提供一個入門指南,一步一步演示如何實現基於CAS的單點登陸。
CAS的官網:http://www.jasig.org/cas
2、演示環境
本文演示過程在同一個機器上的(也能夠在三臺實體機器或者三個的虛擬機上),環境以下:
windows7 64位,主機名稱:michael-pc
JDK 1.6.0_18
Tomcat 6.0.29
CAS-server-3.4.十一、CAS-client-3.2.1
根據演示需求,用修改hosts 文件的方法添加域名最簡單方便(這個很是重要),在文件 C:\Windows\System32\drivers\etc\hosts 文件中添加三條
127.0.0.1 demo.micmiu.com
127.0.0.1 app1.micmiu.com
127.0.0.1 app2.micmiu.com
demo.micmiu.com=>> 對應部署cas server的tomcat,這個虛擬域名還用於證書生成
app1.micmiu.com=>> 對應部署app1 的tomcat
app2.micmiu.com=>> 對應部署app2 的tomcat
3、JDK安裝配置
這個詳細過程就不在描述,若是是免安裝版的,確保環境變量配置正確。
本機環境變量:JAVA_HOME=D:\jdk,若是看到如下信息則表示安裝成功:
4、安全證書配置
有關keytool工具的詳細運用見:http://www.micmiu.com/lang/java/keytool-start-guide/
4.1. 生成證書:
1keytool -genkey -alias ssodemo -keyalg RSA -keysize 1024 -keypass michaelpwd -validity 365 -keystore g:\sso\ssodemo.keystore -storepass michaelpwd
截圖中須要輸入的姓名和上面hosts文件中配置的一致;
keypass 和 storepass 兩個密碼要一致,不然下面tomcat 配置https 訪問失敗;
4.2.導出證書:
1keytool -export -alias ssodemo -keystore g:\sso\ssodemo.keystore -file g:\sso\ssodem
4.3.客戶端導入證書:
1keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file g:\sso\ssodemo.crt -alias ssodem
ps:該命令中輸入的密碼和上面輸入的不是同一個密碼;若是是多臺機器演示,須要在每一臺客戶端導入該證書。
5、部署CAS-Server相關的Tomcat
5.1. 配置HTTPS
解壓apache-tomcat-6.0.29.tar.gz並重命名後的路徑爲 G:\sso\tomcat-cas,在文件 conf/server.xml文件找到:
修改爲以下:
參數說明:
keystoreFile 就是4.1中建立證書的路徑
keystorePass 就是4.1中建立證書的密碼
5.2. 驗證HTTPS配置
其餘按照默認配置不做修改,雙擊%TOMCAT_HOME%\bin\startup.bat 啓動tomcat-cas 驗證https訪問配置:
若是看到上述界面表示https 訪問配置成功。
5.3 部署CAS-Server
CAS-Server 下載地址:http://www.jasig.org/cas/download
本文以cas-server-3.4.11-release.zip 爲例,解壓提取cas-server-3.4.11/modules/cas-server-webapp-3.4.11.war文件,把改文件copy到 G:\sso\tomcat-cas\webapps\ 目下,並重命名爲:cas.war.
啓動tomcat-cas,在瀏覽器地址欄輸入:https://demo.micmiu.com:8443/cas/login ,回車
CAS-server的默認驗證規則:只要用戶名和密碼相同就認證經過(僅僅用於測試,生成環境須要根據實際狀況修改),輸入admin/admin 點擊登陸,就能夠看到登陸成功的頁面:
看到上述頁面表示CAS-Server已經部署成功。
6、部署CAS-Client相關的Tomcat
6.1Cas-Client 下載
CAS-Client 下載地址:http://downloads.jasig.org/cas-clients/
以cas-client-3.2.1-release.zip 爲例,解壓提取cas-client-3.2.1/modules/cas-client-core-3.2.1.jar
藉以tomcat默認自帶的 webapps\examples 做爲演示的簡單web項目
6.2 安裝配置 tomcat-app1
解壓apache-tomcat-6.0.29.tar.gz並重命名後的路徑爲 G:\sso\tomcat-app1,修改tomcat的啓動端口,在文件conf/server.xml文件找到以下內容:
修改爲以下:
啓動tomcat-app1,瀏覽器輸入 http://app1.micmiu.com:18080/examples/servlets/ 回車:
看到上述界面表示tomcat-app1的基本安裝配置已經成功。
接下來複制 client的lib包cas-client-core-3.2.1.jar到 tomcat-app1\webapps\examples\WEB-INF\lib\目錄下, 在tomcat-app1\webapps\examples\WEB-INF\web.xml文件中增長以下內容:
有關cas-client的web.xml修改的詳細說明見官網介紹:
https://wiki.jasig.org/display/CASC/Configuring+the+Jasig+CAS+Client+for+Java+in+the+web.xml
6.3 安裝配置 tomcat-app2
解壓apache-tomcat-6.0.29.tar.gz並重命名後的路徑爲 G:\sso\tomcat-app2,修改tomcat的啓動端口,在文件 conf/server.xml文件找到以下內容:
修改爲以下:
啓動tomcat-app2,瀏覽器輸入 http://app2.micmiu.com:28080/examples/servlets/ 回車,按照上述6.2中的方法驗證是否成功。
同6.2中的複製 client的lib包cas-client-core-3.2.1.jar到 tomcat-app2\webapps\examples\WEB-INF\lib\目錄下, 在tomcat-app2\webapps\examples\WEB-INF\web.xml文件中增長以下內容:
7、 測試驗證SSO
啓動以前配置好的三個tomcat分別爲:tomcat-cas、tomcat-app一、tomcat-app2.
7.1 基本的測試
預期流程: 打開app1url —-> 跳轉cas server 驗證 —-> 顯示app1的應用 —-> 打開app2url —-> 顯示app2應用 —-> 註銷cas server —-> 打開app1/app2 url —-> 從新跳轉到cas server 驗證.
打開瀏覽器地址欄中輸入:http://app1.micmiu.com:18080/examples/servlets/servlet/HelloWorldExample,回車:
跳轉到驗證頁面:
驗證經過後顯示以下:
此時訪問app2就再也不須要驗證:
地址欄中輸入:https://demo.micmiu.com:8443/cas/logout,回車顯示:
上述表示 認證註銷成功,此時若是再訪問 : http://app1.micmiu.com:18080/examples/servlets/servlet/HelloWorldExample 或 http://app2.micmiu.com:28080/examples/servlets/servlet/HelloWorldExample 須要從新進行認證。
7.2 獲取登陸用戶的信息
修改類:webapps\examples\WEB-INF\classes\HelloWorldExample.java 後從新編譯並替換 webapps\examples\WEB-INF\classes\HelloWorldExample.class文件。
HelloWorldExample.java修改後的代碼以下:
再進行上述測試顯示結果以下:
http://app1.micmiu.com:18080/examples/servlets/servlet/HelloWorldExample :
http://app2.micmiu.com:28080/examples/servlets/servlet/HelloWorldExample
從上述頁面能夠看到經過認證的用戶名。
到此已經所有完成了CAS單點登陸實例演示