1、什麼是OAuth?
OAuth是一個受權規範,可使A應用在受限的狀況下訪問B應用中用戶的資源(前提是通過了該用戶的受權,而A應用並不須要也沒法知道用戶在B應用中的帳號和密碼),資源一般以REST API的方式暴露。
2、什麼是OAuth2.0?
有2.0天然有1.0,相比1.0,2.0有以下不一樣:
3、爲何要用OAuth?
傳統的client-server 認證模式下,客戶端通常經過資源全部者的帳號/密碼,來向服務端請求某個受保護的資源。那麼,爲了能讓第三方應用訪問這些受保護的資源,資源全部者可能須要與第三方應用共享本身的帳號/密碼,可是這麼作存在一些問題:
-
第三方應用須要存儲資源全部者的帳號/密碼,以便未來再次使用,而且一般會以明文的方式存儲。
-
第三方應用能訪問資源全部者所有的受保護資源,資源全部者沒法約束其訪問的期限以及可以訪問的資源邊界。
-
資源全部者沒法單獨取消個別第三方應用的訪問權限,要麼所有容許,要麼所有不容許。
OAuth 能夠解決這些問題,方法是引入一個受權層,而且將客戶端與資源全部者的角色分離。OAuth下,客戶端能夠訪問哪些資源受資源全部者控制,而且客戶端的訪問憑證與資源全部者是不一樣的。客戶端再也不使用資源全部者的憑證訪問受保護的資源,而是經過獲取一個access token(一個字符串,可以表 示訪問的邊界,訪問的期限等訪問屬性)。在通過用戶受權後,access token會由一個受權服務器發佈給第三方客戶端。而後,第三方客戶端使用access token到資源服務器訪問受保護的資源。
4、進一步理解OAuth2.0
一、OAuth中涉及的幾個角色:
二、協議流示意圖
-
(1)client請求用戶受權以訪問資源;
-
(2)若是用戶受權,client會接收到一個受權許可;
-
(3)client憑藉受權許可及客戶端身份標識,請求access token;
-
(4)若是client身份和受權許可都認證經過,受權服務器會頒發令牌;
-
(5)client憑藉訪問令牌到資源服務器請求資源;
-
(6)若是訪問令牌有效,資源服務器會返回相應資源給client。
三、該協議流是整體概念,實際會根據使用的受權許可的類型不一樣而有所差別,OAuth2.0有4種受權許可類型:
受權碼從受權服務器得到,受權服務器充當client和resource owner的中間者。client不會直接從Resource Owner請求受權,而是引導Resource Owner到受權服務器,受權服務器會反向引導Resource Owner至client,並帶上受權碼。返回受權碼以前,由受權服務器驗證Resource Owner的身份以及受權狀況,由於ResourceOwner只會在受權服務器作認證,Resource Owner的憑證信息是不會讓client知曉的。受權碼在安全方面帶來了一些重要的好處,好比對客戶端認證的能力,以及避免了直接經過Resource Owner的user-agent(好比瀏覽器)來傳輸access token,使得access token對其餘人不可見,包括Resource Owner本身,大大下降了access token泄露的風險。
Implicit許可類型是針對clients簡化過的受權碼許可類型,在瀏覽器利用腳本語言來實現。使用Implicit類型,用戶受權後,client直接獲取一個access token,而不是獲取一個受權碼。因爲沒有像受權碼同樣的中間憑證產生,因此受權許但是隱式的。因爲這種特性,在某些使用瀏覽器進行URI重定向的場景下,access token可能會暴露。Implicit改善了一些clients的響應效率,可是也帶來了安全隱患,因此建議通常只在Mobile Apps等不那麼容易從URI中獲取信息的應用中而且受權碼類型不可用的場景下使用。
直接使用資源全部者的密碼憑證(好比:用戶名和密碼)做爲受權許可來獲取access token。該類型下雖然client知曉了Resource Owner的憑證,可是能夠經過換取一個長生命週期的access token或 refresh token 來避免長期存儲憑證以便未來再次使用的須要。可是除非client是被高度受信任的,而且受權碼類型不能使用的場景外不建議使用。
客戶端憑證(或其它的認證形式)能夠直接用做受權許可。適用於受權邊界不須要Resource Owner控制或者可以在受權服務器預先配置的場景,好比在多個資源服務器共用統一用戶中心的場景下,資源服務器之間須要相互訪問,此時client可能也是resource owner 或者resource server。
5、如何實現OAuth2.0?
開源界有不少基於各類語言實現的OAuth2.0的框架,咱們能夠根據自身的須要選擇符合本身要求的框架,可是頗有可能分析下來,咱們會發現有些語言領域的OAuth2.0框架並不能知足實際的需求。
好比咱們只想實現相似「一處登陸,到處同行(單點登陸);或者一個賬號多處登陸(聯合登陸,好比使用QQ、微信賬號登陸)」的特性,使用相似Spring Security OAuth就有些過重了(除非你已經再用而且很是熟悉了),而Apache Oltu又過於粗糙,基本只提供了空架子,還要依賴它的各類包,Light OAuth2卻是很輕量,但又和undertow緊耦合,因此自研一套更輕量級的、可擴展的、適用自身業務場景的OAuth2.0框架會顯得更合適。
筆者曾花費一些時間自研了一套OAuth2.0的框架,目前只包含OAuth2.0的受權碼許可類型,支持聯合登陸和單點登陸,擁有完整的統一用戶中心體系,支持用戶登陸認證層和緩存層的自定義。其詳細的時序圖以下:
聯合登陸時序圖: