在設計一個系統的時候大多數都需要一個登陸授權的方案來保證訪問安全和許可權的控制。好在我們有類似於spring這樣的框架,更多的時候只需要完成幾行配置就能工作。這也讓開發者忽略了他的工作流程和原理,就通過這篇文章來認識探討下。首先丟擲一個概念:SSO單點登入(Single Sign On)。
SSO&CAS
其定義為:
SSO是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。它包括可以將這次主要的登入對映到其他應用中用於同一個使用者的登入的機制。它是目前比較流行的企業業務整合的解決方案之一。
SSO這是一個概念方案,其中有我們經常聽到的著名的耶魯大學的CAS系統就是它的一個實現。具體可以瞭解 CAS Architecture,其工程流程圖如下:
其中核心要解決的的是引入鑑權和認證的流程,實現多套系統的單一訪問需要的是同一套授權方案即可。
鑑權和認證
認證(Authentication)和授權(Authorization)總是成對出現,但是不能混為一談。
簡單的來說,認證是用來確定小明是不是真的小明的。授權是限定小明具備哪些許可權的,比如小明只可以看這篇部落格不能修改這篇部落格,而我作者本人可以。
那麼這個流程應該是怎麼樣的呢,每家的方案不能總不一樣吧,那麼就出現了這樣一個標準:OAuth
,現在已經出到2.0了,也就是我們今天要了解的OAuth 2.0
.所以
OAuth2.0是行業標準的授權(Authentication)協議.
OAuth 2.0關注客戶端開發者的簡易性,同時為Web應用,桌面應用和手機,和起居室裝置提供專門的認證流程。
來看官方的工作流描述:
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
複製程式碼
Abstract Protocol Flow,好吧,是挺抽象,尤其是Autorization Grant是怎麼完成的我們還是不得而知。不過我們可以得知想要訪問資源服務,我們最終是拿到授權服務分配的Access Token,OAuth 2.0的授權模式有好幾種,主要還是根據設計的需求。我們就拿最複雜和最完善的一個模式來分析:授權碼模式。同樣,我們先看官方的解釋:
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
複製程式碼
從圖中我們可以看出大概的流程,使用者訪問資源的時候首先要經過授權服務的授權,訪問授權服務的過程使用者通過客戶代理帶上註冊好的Clent ID 和重定向的地址,授權服務驗證好是否正確之後會給到客戶代理一個授權碼,把授權碼帶給客戶端,客戶端可以通過此授權碼才能獲取可訪問的Access Token。前面有總結過,只有拿到有效的Access Token才能暢通的訪問到我們的資源服務。
不過...為什麼要這麼複雜?為什麼不一步到位第一次訪授權服務的時候(User authenticates)就拿到Access Token,而需要通過授權碼去拿到Access Token?
答案是:為了安全
首先這裡需要此類授權碼的情況只成立於是並沒有使用Https去訪問,比我類似於窮x的博主買不起ssl認證服務。因為問題可能出現在給到client端Access Token的方式有關,如果直接藉助的重定向返回AccessToken,這就給了Hacker劫持到Access Token的機會,因為uri可能通過HTTP referrer被傳遞給其它惡意站點,也可能存在於瀏覽器cacher或log檔案中。但是直接重定向返回Authorization Code就不是什麼敏感的資料了,通過Authorization Code再重新校驗去獲取Access Token的時候需要上傳Client金鑰(僅client持有),擁有有效Client Secret 的訪問才能被保證是安全的。
如果你不是類似於博主這樣的窮x,官方推薦也是implicit flow模式,更加快捷安全。
以上,基本上清楚了OAuth2的流程,恰巧勤勞的大神麼也會有些不錯的實現程式碼供大家參考,這裡蒐羅了一個不錯的實現案例:oltu-oauth2-example
結合的畫一個流程圖幫助理解:
重要流程列表
- 註冊應用:獲取client_id,client_secret。
- 請求授權碼:通過client_id獲取授權碼auth_code
- 換取accessToken:通過client_id,client_secret,auth_code獲取AccessToken
- 通過AccessToken訪問資源服務
其中請求授權的過程需要開啟登陸頁面,輸入使用者名稱密碼正確之後再返回auth_code。