寫做提綱php
1. http協議的無鏈接、無狀態特性html
2. 單點登陸、登出的交互是如何進行的:client,application A,application B,認證中心java
3. 全局會話與局部會話node
4. 單點登陸的實現:聯繫代碼web
5. 單點登陸的企業級實現:框架是如何來實現的ajax
6. 單點登陸的安全性spring
7. 單點登陸中的其餘問題:好比令牌如何生成數據庫
如今大多數web應用採用的是browser/server架構,http做爲通訊協議。http是無鏈接、無狀態的協議,這兩個特性都後來web應用的架構和設計點產生了很大的影響。json
無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。跨域
無狀態是指協議對於事務處理沒有記憶能力,服務器不知道客戶端是什麼狀態。即咱們給服務器發送 HTTP 請求以後,服務器根據請求,會給咱們發送數據過來。再次訪問發送HTTP請求以後,服務器會把咱們當成從未服務過的新人同樣,只會根據咱們的請求來響應,和上次以及後來的HTTP請求沒有任何的關聯。
圖1 http請求的無鏈接無狀態特性
HTTP 協議這種特性有優勢也有缺點,優勢在於解放了服務器,每一次請求"點到爲止"不會形成沒必要要鏈接佔用,缺點在於每次請求會傳輸大量重複的內容信息。
客戶端與服務器進行動態交互的 Web 應用程序出現以後,HTTP 無狀態的特性嚴重阻礙了這些應用程序的實現,畢竟交互是須要承前啓後的,簡單的購物車程序也要知道用戶到底在以前選擇了什麼商品。
再好比,在一個須要登陸的系統(目前大多數企業級應用都有登陸功能),我第一次登陸的時候須要輸入帳號密碼。若是沒有其餘任何機制的話,對於這個系統咱們只能登陸,其餘的什麼都幹不了,想一下爲何。
因而,兩種用於保持 HTTP 鏈接狀態的技術就應運而生了,一個是 cookie,而另外一個則是 session。
cookie和session均可以用來解決http協議無狀態的特性,簡單回顧一下它們的區別。
cookie是由網景公司的前僱員Lou Montulli在1993年發明的,現今cookie已經普遍使用了。
cookie 和session 的區別回顧:
1. cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
2. cookie不是很安全,別人能夠分析存放在本地的cookie並進行cookie欺騙,考慮到安全應當使用session。
3. session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能。
4. 瀏覽器對每一個站點的cookie數,以及每一個cookie的大小都是有限制的。
服了這些人了,爲啥轉載不附上原做的地址!!!
Cookie的屬性和跨域問題中有以下描述
個域名下面可能存在着不少個cookie對象,cookie具備多個屬性:
name字段爲一個cookie的名稱
value字段爲一個cookie的值
domain字段爲能夠訪問此cookie的域名,Servlet中經過setDomain()設置
非頂級域名,如二級域名或者三級域名,設置的cookie的domain只能爲頂級域名或者二級域名或者三級域名自己,不能設置其餘二級域名的cookie,不然cookie沒法生成。
頂級域名只能設置domain爲頂級域名,不能設置爲二級域名或者三級域名,不然cookie沒法生成。
二級域名能讀取設置了domain爲頂級域名或者自身的cookie,不能讀取其餘二級域名domain的cookie。因此要想cookie在多個二級域名中共享,須要設置domain爲頂級域名,這樣就能夠在全部二級域名裏面或者到這個cookie的值了。
頂級域名只能獲取到domain設置爲頂級域名的cookie,其餘domain設置爲二級域名的沒法獲取。
而後又發現了一個淘寶、天貓跨域請求實現分析的技術文章:Cookie跨域問題
其實大體原理如此,經過在www.taobao.com 的server端提供一個獲取當前域下全部cookie的 php的請求地址,而後該php獲取到cookie以後將期併成 js 代碼,也就是以上第二個截圖所看到的。而後再在 tmall 採用 jsonp 的方式跨域加載該 js 代碼,從而實現 cookie 的跨域訪問。
單系統的會話機制是如何實現的呢?
上面說到過cookie是存儲客戶端的(瀏覽器),而session是保存在服務器端的。同時咱們也看到,因爲採用服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session機制可能須要藉助於cookie機制來達到保存標識的目的,但實際上它還有其餘選擇。
保存這個session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發揮給服務器。通常這個cookie的名字都是相似於SEEESIONID。
但cookie能夠被人爲的禁止,則必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。常常被使用的一種技術叫作URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫作表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。
上面講到了,單系統登陸中關鍵的部分是要經過cookie來傳遞會話標識來維護會話狀態。可是cookie是有限制的,域名、大小。既然這樣,爲何不將web應用羣中全部子系統的域名統一在一個頂級域名下,例如「*.baidu.com」,而後將它們的cookie域設置爲「baidu.com」,這種作法理論上是能夠的,甚至早期不少多系統登陸就採用這種同域名共享cookie的方式。然而,可行並不表明好,共享cookie的方式存在衆多侷限。首先,應用羣域名得統一;其次,應用羣各系統使用的技術(至少是web服務器)要相同,否則cookie的key值(tomcat爲JSESSIONID)不一樣,沒法維持會話,共享cookie的方式是沒法實現跨語言技術平臺登陸的,好比java、php、.net系統之間;第三,cookie自己不安全。所以,咱們須要一種全新的登陸方式來實現多系統應用羣的登陸,這就是單點登陸。
單點登陸(Single Sign On)解決的問題是登陸一個系統以後就能夠在多個系統之間能夠免登錄訪問。
單點登陸不只僅是登陸還有註銷。
爲了在多個系統之間可以登陸,單點登陸須要一個獨立的認證中心。
在博客單點登陸原理與簡單實現中有一個圖講的很清楚
這裏分兩個部分來描述單點登陸的過程
第一部分是第一次登錄,第一次登陸咱們確定是要輸入帳號、密碼進行登陸的,上圖中也描繪的很清楚
第二部分是已登陸的帳號免登錄到另外一個系統。
cnblogs上還有個專門作單點登陸的,我也是服氣,單點登陸SSO:圖示和講解
6.1 用戶未登陸時訪問子站一,子站一服務器檢測到用戶沒登陸(沒有本站session,由於沒傳過來session對應cookie),因而通知瀏覽器跳轉到SSO服務站點,並在跳轉的URL參數中帶上當前頁面地址,以便登陸後自動跳轉回本頁。
6.2 SSO服務站點檢測到用戶沒有登陸,因而顯示登陸界面。
用戶提交登陸請求到服務端,服務端驗證經過,建立和帳號對應的用戶登陸憑據(token)。
而後,服務端通知瀏覽器把該token做爲SSO服務站點的cookie存儲起來,並跳轉回子站一,跳回子站一的URL參數中會帶上這個token。
6.3 瀏覽器在寫SSO服務站點cookie後,跳轉回子站一。
子站一服務端檢測到瀏覽器請求的URL中帶了單點登陸的token,因而把這個token發到SSO服務站點驗證。
SSO服務端站點拿token解密出用戶帳號,把帳號信息中容許子站一訪問的部分返回給子站一。
子站一根據返回的信息生成用戶在本站的會話,把會話對應cookie寫入瀏覽器,從而完成在本站的登入以及會話保持。以後用戶訪問再子站一時,都會帶上這個cookie,從而保持在本站的登陸狀態。
6.4 用戶再訪問子站二。子站二服務器檢測到用戶沒登陸,因而通知瀏覽器跳轉到SSO服務站點。
6.5 瀏覽器訪問SSO服務站點時會帶上上述6.2環節建立的token這個cookie。SSO服務站點根據該token能找到對應用戶,因而通知瀏覽器跳轉回子站二,並在跳轉回去的URL參數中帶上這個token。
6.6 子站二服務端檢測到瀏覽器請求的URL中帶上了單點登陸的token,因而又會走上述6.3對應步驟,完成用戶在本站的自動登陸。
這裏有個問題是在登陸系統2的時候是要進行驗證的,這個時候沒有帳號信息,拿頭作驗證?
在本文講cookie的時候提到過一篇文章講taobao與tmall作跨域的cookie的方法能夠用,假如cookie被禁用了咋辦,我仍是想實現單點登陸怎麼辦呢?不跨域的cookie使用只能在同一個二級域名下了。
京東的跨域sso
js遍歷sso,經過jQuery.ajax()方法對其中的每條數據發起跨域的jsonp請求;
能夠看到返回一個重定向的Response,並且是跨域的重定向,因爲發起的是跨域的jsonp請求,因此瀏覽器會根據返回的重定向url發起一次請求,也就是最後的跨域設置Cookie的請求
SSO實施和業務系統開發不一樣,它是技術點密集但工做量少的業務。若是你的開發人員還要爲「如何跨域傳token」、「如何讀寫AD」之類現學摸索,那實施結果每每存在較大安全漏洞,也會致使工期不可預測。這一塊的不少現成產品都有特定的實施要求和侷限性(本人曾填坑Oracle的OIM 和 ESSO),加之實施人員對產品熟悉程度不一,致使企業稍有自身特定的狀況,就會要花費大量工時研究調整,甚至最終沒法按需交付。
個人實現中,認證系統和應用系統是經過url參數來傳遞ticket,可能存在一些不穩定因素。應用系統的每次請求都會經過HTTP遠程到認證系統進行驗證ticket,速度上應該會慢一些,這裏能夠改進一步,在每一個應用系統中也維護一份tickets,驗證時,首先到本系統中驗證,若是不存在,再遠程到認證系統進行驗證,但這也增長了應用系統的代碼量。
在登陸的過程當中起始出現了兩種級別的會話
若是用SOA來作單點登陸的話還挺簡單的
spring + shiro + cas 實現sso單點登陸
sso-shiro-cas
spring下使用shiro+cas配置單點登陸,多個系統之間的訪問,每次只須要登陸一次,項目源碼
系統模塊說明
cas: 單點登陸模塊,這裏直接拿的是cas的項目改了點樣式而已
doc: 文檔目錄,裏面有數據庫生成語句,採用的是MySQL5.0,數據庫名爲db_test
spring-node-1: 應用1
spring-node-2: 應用2
其中node1跟node2都是採用spring + springMVC + mybatis 框架,使用maven作項目管理
最近作項目遇到了多個系統權限用的是shiro框架,須要作成單點登陸,雖然shiro爲單點登陸提供了shiro-cas的方案,可是不太符合咱們現有項目的框架,如今和你們分享一下我是如何實現單點登陸。總體思路是參考cas。
框架圖:
流程介紹
也就是說在單點登陸實現的時候仍是要依靠連接重定向與cookie。
若是不用cookie該怎麼辦呢?
此前使用過cas作單點登陸,作了一半發現這個不可行,由於應用場景的限制不能基於cookie來識別用戶經過驗證與否。
在sof上面也提過問,就是說讓在url裏面加入token,不過不太理解。
請問你們是否有作過相關的東西,若是有的話,能幫我解惑嗎?
其實 Cookie 在用戶登陸裏的做用也只是存一個 Session ID 而已,你能夠本身實現一套 Session 機制把 Session ID 經過 URL 來傳遞。
在好久好久之前那些手機版網站(那時候手機廣泛不支持 Cookie)就是這麼作的。
其實與其在網站上面作這麼噁心的 workaround,不如在客戶機上面處理。好比說用具有回話隔離功能的瀏覽器(好比說 Google Chrome 登陸不一樣的 Google 帳戶後相互之間的 Cookie 就是不互通的)。
上面說過cookie是不能跨域的,經過特殊設置setDomain()能夠作到跨同一個大域下的兩個子域。
CAS框架:CAS(Central Authentication Service)是實現SSO單點登陸的框架。
Spring Security + CAS實現單點登陸
應該說單點登陸是門戶系統的核心組件之一.也是門戶系統的安全屏障。經過單點登陸驗證成功後,用戶能夠訪問門戶下全部應用系統,因此保證單點登陸的安全是保證門戶系統安全的前提。可是,現有的產品在單點登陸的安全性還有一些不足:
(1)安全性考慮不全面
各個解決方案在安全性考慮不是很全面,沒有針對門戶的複雜性,採用多種技術結合保證門戶的安全,例如微軟的Passport採用Kerberos認證機制來完成身份認證工做,服務器與用戶共事的祕密是用戶的票據,服務器在迴應時不驗證用戶的真實性,假設只有合法用戶擁有口令字。若是攻擊者記錄申請回答報文,就易造成重發攻擊。
(2)安全兼容性不高
不少解決方案的安全性是創建在對本身產品標準的兼容基礎上的,對異構的系統安全性支持很差,例如IBM的WebSphere則過於依賴於WebSphere Domino環境,對其它異構系統的安全兼容性很差。
(3)信息傳輸缺少安全保證
在門戶服務器與應用服務器通訊過程當中大多數方案採用明文形式傳送敏感信息,這些信息很容易被竊取,導致重要信息泄露。另外,在通訊過程當中大多數方案也沒有對關鍵信息進行簽名,容易遭到假裝攻擊。
(4)Web服務的安全缺陷
因爲單點登陸基本上是基於Web服務實現的,因此單點登陸天生就繼承了Web服務的安全缺陷,這也每每被各個解決方案所忽略。
首先應該避免用戶憑證的COOKIE泄露,在用戶端,由於內存COOKIE比文件COOKIE更難被截取,特別是通過特殊處理的瀏覽器,要截取內存COOKIE幾乎不可能,並且當瀏覽器關閉時,內存COOKIE失效,因此應該使用內存COOKIE而非文件COOKIE,這也是不少使用文件COOKIE的論壇賬號常常被盜的緣由。
爲進一步減小風險,不該該在COOKIE中直接保存用戶憑證,而是使用一個無心義的標識符如UUID來表示,而登錄服務能夠經過這個UUID查找到真正的用戶憑證,這個標誌符隨機生成,即便同一用戶登錄,獲得的UUID也不同,因此不能重複使用,這樣即便偶爾泄露一次,也不會形成長期影響。爲了提升COOKIE的截取難度,能夠設置一個有效時間,只有在有效期內的COOKIE是合法的,超過有效期的COOKIE將被忽略,使用超過有效期的用戶依然須要從新輸入驗證信息。這樣也帶來一個不便的地方,就是用戶若是兩次業務邏輯之間的切換時間超過了COOKIE的有效期,那麼用戶還得從新輸入驗證信息,達不到單點登錄的效果,因此如何取捨,要根據業務邏輯而定。
其次由於http使用明文傳輸,經過網絡偵聽的方式很容易獲取COOKIE,因此用戶到登錄服務間的鏈接應該採用https
登錄代理中使用COOKIE來保存SESSION的狀況,這是大多數Web應用服務器採用的方法。這種狀況相似登錄服務使用COOKIE來保存用戶憑證,典型的欺騙是黑客B截獲了正經常使用戶A的SESSION COOKIE,而後B訪問業務邏輯時附帶這個COOKIE,Web應用服務器會認爲B就是A,因而A能獲得的用戶憑證,B也能獲得,B就成了A的影子,與A具備相同的操做權限。因此關鍵問題仍是如何避免SESSION COOKIE的泄露,由於這個COOKIE由Web應用服務器控制,因此除了在網絡傳輸時使用https,基本上沒有其餘辦法能夠下降風險。除了使用COOKIE做爲SESSION標記,不少Web應用服務器也支持隱式域的方式,就是Web應用服務器在頁面自動建立一個隱藏的表單項做爲SESSION標記,頁面提交時該表單自動被提交,Web應用服務器經過這個表單項來肯定用戶SESSION。這個是更不安全的作法,由於不少很簡單的方法就能夠獲取頁面表單項的數據,比獲取內存COOKIE容易不少。
業務邏輯、登錄代理、登錄服務間存在消息傳遞,業務邏輯和登錄代理部署在一個Web應用服務器中,消息傳遞比較安全。登錄代理和登錄服務一般處在不一樣的Web應用服務器中,而且一般在地域上也不一致,登錄代理和登錄服務間的安全隱患除了消息泄露,還有相互信任的問題。
目前已實現單點登陸的典型模型有經紀人模型、代理模型、代理和經紀人模型、網管模型和令牌模型等,比較成熟的解決方案有微軟的 Passport、IBM的WebSphere Portal Server、CAS,這些產品雖能較好的實現單點登陸,但存在系統複雜、使用成本和學習曲線高、不能知足小型應用系統集成等缺點。
小型系統的令牌用UUID?