1. 程式人生 > >OAuth 授權過程工作原理講解

OAuth 授權過程工作原理講解

sch 網絡日誌 dir 學生 del 解決 oca href word

轉自:http://www.imooc.com/article/10931

在一個單位中,可能是存在多個不同的應用,比如學校會有財務的系統會有學生工作的系統,還有圖書館的系統等等,如果每個系統都用獨立的賬號認證體系,會給用戶帶來很大困擾,也給管理帶來很大不便。所以需要設計一種統一登錄的解決方案。比如我登陸了百度賬號,進貼吧時發現已經登錄了,進糯米發現也自動登錄了。常見的有兩種情況,一種是SSO(單點登錄)效果是一次輸入密碼多個網站可以識別在線狀態;還有一種是多平臺登錄,效果是可以用一個賬號(比如QQ賬號)登錄多個不同的網站。

SSO與多平臺登錄

SSO一般用於同一單位的多個站點的登陸狀態保持,技術上一般參考CAS協議;多平臺登錄一般是Oauth體系的協議,有多種認證模式但是不具備會話管理和狀態保持。
不過從本質上講,我覺得兩者都是通過可信的第三方進行身份驗證,如果說同一單位的多個子系統共同只圍繞一個第三方賬戶(可以稱為認證中心)進行多平臺登錄驗證,那麽在第三方平臺登錄後再訪問其他網站,效果和統一登錄是差不多的。此外,Oauth2還有個好處就是可以實現跨平臺的登錄管理,因為他的認證過程不依賴於session和cookie,比如對於移動端設備,以及在前後端分離後這種登錄認證方式也可以起到很大作用。
這篇文章裏我就著結合之前項目中整合過的OAUTH2來講一講這種登錄認證的過程。項目是基於Shiro+ALTU實現,參考方案mkk/oauth2-shiro - 碼雲 - 開源中國 。

oauth2的基本概念

在Oauth中至少是有用戶,應用服務器,認證服務器這幾個角色在交互。OAuth的作用就是讓"客戶端"安全可控地獲取"用戶"的授權,與"應用服務器"進行互動。

OAuth2的基本流程

用戶通過瀏覽器訪問一個應用,比如我要上慕課網學習。

  1. 網站要求我登錄,我選擇使用QQ登錄,這裏的QQ登錄就是那個認證服務器。
  2. 這個時候慕課提供的QQ登錄鏈接會把我帶到QQ登錄頁面
  3. 在QQ的登錄頁面完成登錄後,選擇授權,也就是允許慕課網獲取我的資料。
  4. 這個時候我們看到瀏覽器經過幾次跳轉後返回慕課網,這個時候我們已經完成了登錄。

重點在於幾次跳轉的過程中,慕課網和QQ登錄的服務之間還有過幾次交互。

  1. 我們選擇了授權的時候QQ登錄服務器會根據慕課跳轉到QQ時候給出的重定向鏈接返回給慕課網一個code,這個code代表QQ的登錄服務器認可慕課網這個應用服務器的這個請求是合法的予以放行.
  2. 慕課這個時候就會用這個code再次向QQ登錄服務發起請求服務令牌(token)。
  3. 拿到這個令牌之後,接下來慕課需要用戶的一些基本信息時就可以通過在向QQ服務提交的請求頭裏帶上這個令牌,令牌驗證通過就可以拿到用戶資源。

這一部分的操作是應用服務器和驗證服務器之間的交互,這個過程對用戶是透明的。這個過程中慕課網是不需要知道用戶的賬號密碼也可以完成對用戶身份的認證,這個token就可以用來標識用戶資源。
官方的運行流程圖是這樣的:
技術分享

OAuth的幾種認證模式

上述講的是OAuth2中支持的授權碼(CODE)方式的認證流程,也是其支持的四種認證方式裏最復雜的,其他的三種種包括:

  1. 簡化模式(implicit),(在redirect_uri 的Hash傳遞token; Auth客戶端運行在瀏覽器中,如JS,Flash)
  2. 密碼模式(resource owner password credentials),將用戶名,密碼傳過去,直接獲取token;
  3. 客戶端模式(client credentials),無用戶,用戶向客戶端註冊,然後客戶端以自己的名義向‘服務端‘獲取資源;
    詳細的OAuth2資料參考理解OAuth 2.0|阮一峰的網絡日誌
    分別適用不同場景,復雜度也比授權碼模式要低,所以這裏就只說說授權碼模式的具體過程。

CODE方式認證實例

假設現在有一個應用服務器跑在我本機8000端口,認證服務器在8090端口。在需要用戶登錄時候把用戶帶到以下的一個URL.

http://localhost:8090/oauth/authorize?response_type=code&scope=read write&client_id=test&redirect_uri=http://localhost:8000/login&state=09876999

我們註意到幾個重要的參數:
技術分享

  • response_type:表示授權類型,就是上面講的那四種類型,這裏用的是code方式。
  • client_id:表示客戶端的ID,代表哪個應用請求驗證
  • redirect_uri:表示重定向URI,驗證以後的回調地址,一般用來接收返回的code,以及做下一步處理。
  • scope:表示申請的權限範圍,
  • state:表示客戶端的當前狀態,可以指定任意值,認證服務器會原封不動地返回這個值。作為安全校驗。

如果以上步驟都通過的話,認證服務器會轉向這個會調地址,帶上發放的Code碼,類似如下:

http://localhost:8000/login?code=bca654ab6133ab3cbc55bb751da93b1c&state=09876999

可以看到帶回了返回的參數,以及原樣返回的狀態碼。

應用服務器這時候拿到返回的code去換token,發起如下的一個請求:

http://localhost:8090/oauth/token?client_id=test&client_secret=test&grant_type=authorization_code&code=bca654ab6133ab3cbc55bb751da93b1c&redirect_uri=http://localhost:8000/login&scope=read%20write&state=09876999
與之前請求類似只是多了一個code字段,去驗證客戶端的合法性。

技術分享
驗證服務器會在收到code以後去查找是否有支持這種code的處理器,如果有則發放token。



OAuth 授權過程工作原理講解