實現 OAuth2 單點登陸SSO—單點登陸和OAuth2概述

什麼是單點登陸

單點登陸(Single Sign On)簡稱爲SSO,在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統。比方說阿里巴巴有淘寶、天貓、聚划算等應用網站,而他們的登陸系統卻有且只有一個,不管是在哪一個應用跳轉到登陸頁面用戶只要輸入用戶名(郵箱或手機號)和密碼登陸以後都能在其它幾個應用之間相互跳轉而無需再次登陸,也就是說你只須要註冊一個帳號能夠訪問淘寶、天貓或聚划算應用了,而不須要再在淘寶上面註冊一個帳號,天貓上面註冊一個帳號或者在聚划算上面註冊一個帳號了,想一想是否是很是爽!html

OAuth2

SSO是一種思想,或者說是一種解決方案,使用的是OAuth2相關一整套流程去實現的。json

OAuth2.0 定義了四種角色

  • resource owner(資源全部者,也就是咱們親愛的用戶本身)
  • resource server(資源服務器,也就是用戶本身的資源所在的服務器)
  • client(客戶端,瀏覽器)
  • authorization server(受權服務器,也就是認證和受權的地方)

OAuth運行流程

該圖展現的是四種角色之間的關聯關係,若是你弄懂了這張圖,那麼你就完成了一半。下面我來解釋下這張圖包含的意義:
(A)  客戶端向資源全部者(用戶)請求其受權瀏覽器

說人話:就是用戶名和密碼登陸,驗證用戶的意思

(B)  客戶端收到資源全部者(用戶)的受權許可,這個受權許但是一個表明資源全部者受權的憑據服務器

說人話:客戶端獲得用戶的憑據也就是用戶名和密碼

(C)  客戶端向受權服務器請求訪問令牌,並出示受權許可app

說人話:用戶請求令牌token,並把本身的用戶名和密碼給了受權服務器

(D)  受權服務器對客戶端身份進行認證,並校驗受權許可,若是都是有效的,則發放訪問令牌工具

說人話:受權服務器證實了你就是你本身以後就發放了令牌token

(E)  客戶端向資源服務器請求受保護的資源,並出示訪問令牌網站

說人話:用戶經過受權服務器返回的token 訪問了本身的資源

(F)  資源服務器校驗訪問令牌,若是令牌有效,則提供服務url

說人話:資源服務器看到是你的令牌就把你的相關數據信息返回給客戶端

上面講解了客戶端獲取了用戶憑據再經過受權服務器返回的token訪問本身的資源服務這樣的一個流程,下面咱們就來說解一下,受權服務器經過什麼方式返回token給客戶端?spa

OAuth 2.0 規定了四種得到令牌的流程

  • 受權碼(authorization-code)
  • 密碼式(password)
  • 客戶端憑證(client credentials)
  • 隱藏式(implicit)

第一種受權方式:受權碼(authorization-code)

概念:受權碼方式,指的是第三方應用去受權服務端先申請一個code,而後再用該code獲取令牌token。
使用場景:多應用

(A)  客戶端經過將資源全部者的用戶代理指向受權端點來啓動這個流程。客戶端包含它的客戶端標識符,請求範圍,本地狀態,和重定向URI,在訪問被容許(或者拒絕)後受權服務器當即將用戶代理返回給重定向URI。
(B)  受權服務器驗證資源全部者(經過用戶代理),並肯定資源全部者是否授予或拒絕客戶端的訪問請求。
(C)  假設資源全部者受權訪問,那麼受權服務器用以前提供的重定向URI(在請求中或在客戶端時提供的)將用戶代理重定向回客戶端。重定向URI包括受權碼和前面客戶端提供的任意本地狀態。
(D)  客戶端用上一步接收到的受權碼從受權服務器的令牌端點那裏請求獲取一個訪問令牌。
(E)  受權服務器對客戶端進行認證,校驗受權碼,並確保這個重定向URI和第三步(C)中那個URI匹配。若是校驗經過,則發放訪問令牌,以及可選的刷新令牌。3d

上面流程中具體須要發送和返回的請求參數寫法,下面分解成四步來講明:

Authorization Request

  • response_type:必須的。值必須是"code"。
  • client_id:必須的。客戶端標識符。
  • redirect_uri:可選的,驗證成功以後返回的url。
  • scope:可選的。請求訪問的範圍。
  • state:推薦的。一個不透明的值用於維護請求和回調之間的狀態。受權服務器在將用戶代理重定向會客戶端的時候會帶上該參數。

客戶端會發送相似這樣的一個請求給受權服務端:

GET /authorize?response_type=code&client_id=s6BhdRkqt3&redirect_uri=https://client.example.com/cb&state=xyz
HTTP/1.1  
Host: server.example.com

Authorization Response

  • code:必須的。受權服務器生成的受權碼。受權代碼必須在發佈後不久過時,以減小泄漏的風險。建議最大受權代碼生命期爲10分鐘。客戶端不得屢次使用受權代碼。若是受權代碼不止一次使用,受權服務器必須拒絕請求,並在可能的狀況下撤銷先前基於該受權代碼發佈的全部令牌。受權代碼是綁定到客戶端標識符和重定向URI上的。
  • state:若是以前客戶端受權請求中帶的有"state"參數,則響應的時候也會帶上該參數。

客戶端會收到受權服務端發送過來這樣的一個請求:

HTTP/1.1 302 Found  
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

Access Token Request

  • grant_type:必須的。值必須是"authorization_code"。
  • code:必須的。值是從受權服務器那裏接收的受權碼。
  • redirect_uri:若是在受權請求的時候包含"redirect_uri"參數,那麼這裏也須要包含"redirect_uri"參數。並且,這兩處的"redirect_uri"必須徹底相同。
  • client_id:若是客戶端不須要認證,那麼必須帶的該參數。
  • client_secret
POST /token HTTP/1.1  
Host: server.example.com  
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https://client.example.com/cb

說明:上面的Authorization是用戶經過工具轉換的,若是不加這個,用戶必須在連接裏面加上client_id=xxx&client_secret=xxx

Access Token Response

這樣受權服務器就返回token給客戶端了:

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"example",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "example_parameter":"example\_value"
  }

第二種受權方式:密碼式(password)

概念:若是你高度信任某個應用,用戶直接把用戶名和密碼告訴該應用。該應用就使用你的密碼來申請令牌,這種方式稱爲"密碼式"。
使用場景:單應用

(A)  資源全部者提供他的用戶名和密碼給客戶端
(B)  客戶端攜帶從資源全部者那裏收到的憑證去受權服務器的令牌端點那裏請求獲取訪問令牌
(C)  受權服務器對客戶端進行身份認證,並校驗資源全部者的憑證,若是都校驗經過,則發放訪問令牌

上面流程中具體須要發送和返回的請求參數寫法,下面分解成兩步來講明:

Access Token Request

  • grant_type :必須的。並且值必須是"password"。
  • username :必須的。資源全部者的用戶名。
  • password :必須的。資源全部者的密碼。
  • scope:可選的。
POST /token HTTP/1.1  
Host: server.example.com  
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW  
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w

說明:上面的Authorization是用戶經過工具轉換的,若是不加這個,用戶必須在連接裏面加上client_id=xxx&client_secret=xxx

Access Token Response

HTTP/1.1 200 OK  
Content-Type: application/json;charset=UTF-8  
Cache-Control: no-store  
Pragma: no-cache

{  
 "access_token":"2YotnFZFEjr1zCsicMWpAA",  
 "token_type":"example",  
 "expires_in":3600,  
 "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",  
 "example_parameter":"example\_value"  
}

本文主要講解第一種受權方式:受權碼(authorization-code),像密碼式、客戶端憑證和隱藏式你們能夠自行百度瞭解。

參考

OAuth 2.0 的四種方式
理解OAuth 2.0
OAuth2實現單點登陸SSO
OAuth 2.0詳解

相關文章
相關標籤/搜索