個人 OAuth2 全部文章
- Spring Security 與 OAuth2(介紹):http://www.lxweimin.com/p/68f22f9a00ee
- Spring Security 與 OAuth2(授權(quán)服務(wù)器):http://www.lxweimin.com/p/227f7e7503cb
- Spring Security 與 OAuth2(資源服務(wù)器):http://www.lxweimin.com/p/6dd03375224d
- Spring Security 與 OAuth2(客戶端):http://www.lxweimin.com/p/03e515c2b43f
- Spring Security 與 OAuth2(相關(guān)類參考):http://www.lxweimin.com/p/c2395772bc86
- Spring Security 與 OAuth2(完整案例):http://www.lxweimin.com/p/d80061e6d900
摘要:使用OAuth2 認(rèn)證的好處就是你只需要一個賬號密碼,就能在各個網(wǎng)站進(jìn)行訪問,而面去了在每個網(wǎng)站都進(jìn)行注冊的繁瑣過程,如:很多網(wǎng)站都可以使用微信登錄,網(wǎng)站作為第三方服務(wù)、微信作為服務(wù)提供商
OAuth2 角色
- resource owner:資源所有者(指用戶)
- resource server:資源服務(wù)器存放受保護(hù)資源,要訪問這些資源,需要獲得訪問令牌(下面例子中的 Twitter 資源服務(wù)器)
- client:客戶端代表請求資源服務(wù)器資源的第三方程序(下面例子中的 Quora)客戶端同時也可能是一個資源服務(wù)器
- authrization server:授權(quán)服務(wù)器用于發(fā)放訪問令牌給客戶端(下面例子中的 Twitter 授權(quán)服務(wù)器)
OAuth2 工作流程例子
- 客戶端 Quora 將自己注冊到授權(quán)服務(wù)器上
- 用戶訪問 Quora 主頁,它顯示了各種登陸選項
- 當(dāng)用戶點擊使用 Twitter 登陸時,Quora 打開一個新窗口,將用戶重定向到 Twitter 的登陸頁面上
- 在這個新窗口中,用戶使用他的賬號密碼登陸了 Twitter
- 如果用戶之前未授權(quán) Quora 應(yīng)用程序使用他們的數(shù)據(jù),則 Twitter 要求用戶授權(quán) Quora 來訪問用戶信息權(quán)限,如果用戶已授權(quán) Quora,此步驟則被跳過
- 經(jīng)過正確的身份驗證,Twitter 將用戶和一個身份驗證代碼重定向到 Quora 的重定向 URI
- Quora 發(fā)送客戶端 ID、客戶端令牌和身份驗證代碼到 Twitter
- Twitter 驗證這些參數(shù)后,將訪問令牌發(fā)送到 Quora
- 成功獲取訪問令牌后用戶被登陸到 Quora 上,用戶登錄 Quora 后點擊他們的個人資料頁面
- Quora 從 Twitter 資源服務(wù)器請求用戶的資源,并發(fā)送訪問令牌
- Twitter 資源服務(wù)器使用 Twitter 授權(quán)服務(wù)器驗證訪問令牌
- 成功驗證訪問令牌后,Twitter 資源服務(wù)器向 Quora 提供所需要的資源
- Quora 使用這些資源,并最終顯示用戶的個人資料頁面
dtcoz.png
OAuth2 授權(quán)模式(出自阮一峰OAuth2博客)
授權(quán)碼模式
- 授權(quán)碼模式是功能最完整、流程最嚴(yán)密的授權(quán)模式,它的特點是通過客戶端的后臺服務(wù)器,與“服務(wù)器提供”的認(rèn)證服務(wù)器進(jìn)行互動
9434708-a464c0c64ca6ee9a.png
- 它的步驟如下:
- (A)用戶訪問客戶端,后者將前者導(dǎo)向認(rèn)證服務(wù)器
- (B)用戶選擇是否給予客戶端授權(quán)
- (C)假設(shè)用戶給予授權(quán),認(rèn)證服務(wù)器將用戶導(dǎo)向客戶端事先指定的“重定向 URI”,同時附上一個授權(quán)碼
- (D)客戶端收到授權(quán)碼,附上早先的“重定向 URI”向認(rèn)證服務(wù)器申請令牌,這一步是在客戶端的后臺服務(wù)器上完成的,對用戶不可見
- (E)認(rèn)證服務(wù)器核對了授權(quán)碼和重定向URI,確認(rèn)無誤后向客戶端發(fā)送令牌和更新令牌
- 上述步驟中所需要的參數(shù):
- A步驟中,客戶端申請認(rèn)證的 URI,包含以下參數(shù):
- repsone_type:授權(quán)類型,必選,此處固定值“code”
- client_id:客戶端的ID,必選
- client_secret:客戶端的密碼,可選
- redirect_uri:重定向URI,可選
- scope:申請的權(quán)限范圍,可選
- state:客戶端當(dāng)前的狀態(tài),可以指定任意值,認(rèn)證服務(wù)器會原封不動的返回這個值
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
- C步驟中,服務(wù)器回應(yīng)客戶端的URI,包含以下參數(shù):
- code:表示授權(quán)碼,必須按,該碼有效期應(yīng)該很短,通常10分鐘,客戶端只能使用一次,否則會被授權(quán)服務(wù)器拒絕,該碼與客戶端 ID 和 重定向 URI 是一一對應(yīng)關(guān)系
- state:如果客戶端請求中包含著歌參數(shù),認(rèn)證服務(wù)器的回應(yīng)也必須一模一樣包含這個參數(shù)
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
- D步驟中,客戶端向認(rèn)證服務(wù)器申請令牌的HTTP請求,包含以下參數(shù):
- grant_type:表示使用的授權(quán)模式,必選,此處固定值為“authorization_code”
- code:表示上一步獲得的授權(quán)嗎,必選
- redirect_uri:重定向URI,必選,與步驟 A 中保持一致
- client_id:表示客戶端ID,必選
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%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
- E步驟中,認(rèn)證服務(wù)器發(fā)送的HTTP回復(fù),包含以下參數(shù):
- access_token:表示令牌,必選
- token_type:表示令牌類型,該值大小寫不敏感,必選,可以是 bearer 類型或 mac 類型
- expires_in:表示過期時間,單位為秒,若省略該參數(shù),必須設(shè)置其它過期時間
- refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選
- scope:表示權(quán)限范圍
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" }
- 從上面代碼可以看到,參數(shù)使用 JSON 格式發(fā)送(Content-Type: application/json),才外,HTTP頭信息中明確指定不得緩存
- A步驟中,客戶端申請認(rèn)證的 URI,包含以下參數(shù):
簡化模式
- 簡化模式不通過第三方應(yīng)用程序的服務(wù)器,直接在瀏覽器中向認(rèn)證服務(wù)器申請令牌,跳過了“授權(quán)碼”這個步驟
bg2014051205.png
- 它的步驟如下:
- (A)客戶端將用戶導(dǎo)向認(rèn)證服務(wù)器
- (B)用戶決定是否給予客戶端授權(quán)
- (C)假設(shè)用戶給予授權(quán),認(rèn)證服務(wù)器將用戶導(dǎo)向客戶端指定的“重定向URI”,并在URI的Hash部分包含了訪問令牌
- (D)瀏覽器向資源服務(wù)器發(fā)出請求,其中不包括上一步收到的Hash值
- (E)資源服務(wù)器返回一個網(wǎng)頁,其中包含了代碼可以獲取Hash值中的令牌
- (F)瀏覽器執(zhí)行上一步獲得的腳本,取出令牌
- (G)瀏覽器將令牌發(fā)給客戶端
- 上述步驟中所需要的參數(shù):
- A步驟中,客戶端發(fā)出HTTP請求,包含以下參數(shù):
- response_type:表示授權(quán)類型,此處固定值為"token",必選
- client_id:表示客戶端ID,必選
- redirect_uri:表示重定向URI,可選
- scope:表示權(quán)限范圍,可選
- state:表示客戶端當(dāng)前狀態(tài),可指定任意值,認(rèn)證服務(wù)器會原封不動返回這個值
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com
- C步驟中,認(rèn)證服務(wù)器回應(yīng)客戶端的URI,包含以下參數(shù):
- access_token:表示訪問令牌,必選
- token_type:表示令牌類型,該值大小寫不敏感,必選
- expires_in:表示過期時間,單位為秒
- scope:表示權(quán)限范圍,如果與客戶端申請的范圍一致,可忽略
- state:如果客戶端請求中包含這個參數(shù),認(rèn)證服務(wù)器也要返回一模一樣的參數(shù)
HTTP/1.1 302 Found Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600
- A步驟中,客戶端發(fā)出HTTP請求,包含以下參數(shù):
- 上面例子中,認(rèn)證服務(wù)器用HTTP頭信息的Location欄,指定瀏覽器重定向的網(wǎng)址,注意,這個網(wǎng)址的Hash部分包含了令牌
- 根據(jù)D步驟,下一步瀏覽器會訪問Location指定的網(wǎng)址,但是Hash部分不會被發(fā)送,接下來的E步驟,服務(wù)提供商的資源服務(wù)器發(fā)送過來的代碼,提取出Hash令牌
密碼模式
密碼模式中,用戶向客戶端提供自己的用戶名和密碼,客戶端使用這些信息向“服務(wù)提供商”索要授權(quán)
在這種模式中,用戶必須把密碼給客戶端,但客戶端不得存儲密碼,這通常在用戶對客戶端高端信任的情況下,比如客戶端是操作系統(tǒng)的一部分,由一個著名的公司出品,而認(rèn)證服務(wù)器只有在其它授權(quán)模式無法執(zhí)行的情況下,才考慮該模式
9434708-6165f69e2bfc8881.png
- 它的步驟如下:
- (A)用戶向客戶端提供用戶名和密碼
- (B)客戶端將用戶名密碼發(fā)送認(rèn)證給服務(wù)器,向后者請求令牌
- (C)認(rèn)證服務(wù)器確認(rèn)無誤后,向客戶端提供訪問令牌
- 上述步驟中所需要的參數(shù):
- B步驟中,客戶端發(fā)出HTTP請求,包含以下參數(shù):
- grant_type:授權(quán)類型,必選,此處固定值“password”
- username:表示用戶名,必選
- password:表示用戶密碼,必選
- scope:權(quán)限范圍,可選
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
- C步驟中,認(rèn)證服務(wù)器向客戶端發(fā)送訪問令牌,下面是一個例子:
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" }
- B步驟中,客戶端發(fā)出HTTP請求,包含以下參數(shù):
客戶端模式
- 客戶端模式指客戶端以自己名義,而不是用戶名義,向“服務(wù)提供商”進(jìn)行認(rèn)證,嚴(yán)格地說,客戶端模式不屬于OAuth框架要解決的問題,在這種模式中,用戶直接向客戶端注冊,客戶端以自己名義要求“服務(wù)提供商”提供服務(wù)
bg2014051207.png
它的步驟如下:
-(A):客戶端向認(rèn)證服務(wù)器進(jìn)行身份認(rèn)證,并要求一個訪問令牌
-(B):認(rèn)證服務(wù)器確認(rèn)無誤后,向客戶端提供訪問令牌-
上述步驟中所需要的參數(shù):
-
A步驟中,客戶端發(fā)出HTTP請求,包含以下參數(shù):
- granttype:表示授權(quán)類型,此處固定值為“clientcredentials”,必選
- scope:表示權(quán)限范圍,可選
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=client_credentials
-
B步驟中,認(rèn)證服務(wù)器向客戶端發(fā)送訪問令牌,下面是一個例子
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, "example_parameter":"example_value" }
-
更新令牌
- 如果用戶訪問的時候,客戶端“訪問令牌”已經(jīng)過期,則需要使用“更新令牌”申請一個新的令牌
- 客戶端發(fā)出更新令牌請求,包含以下參數(shù):
- granttype:表示授權(quán)模式,此處固定值為“refreshtoken”,必選
- refresh_token:表示早前收到的更新令牌,必選
- scope:表示申請權(quán)限范圍,不得超出上一次申請的范圍,若省略該參數(shù),則表示與上一次一樣
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA