@
一、OAuth2.0是什么?
1.1 OAuth2.0簡介
OAuth 2.0是目前最流行的授權機制,用來授權第三方應用
OAuth是一種開放協議, 允許用戶讓第三方應用以安全且標准的方式獲取該用戶在某一網站,移動或者桌面應用上存儲的秘密的資源(如用戶個人信息,照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。
OAuth 1.0協議(RFC5849)作為一個指導性文檔發布,是一個小社區的工作成果。
本標准化規范在OAuth 1.0的部署經驗之上構建,也包括其他使用案例以及從更廣泛的IETF社區收集到的可擴展性需求。
OAuth 2.0協議不向后兼容OAuth 1.0。這兩個版本可以在網絡上共存,實現者可以選擇同時支持他們。
1.2 OAuth2.0官方文檔
官網:https://oauth.net/2/ ,官網只有英文版文檔,您也可以參考翻譯過來的文檔,鏈接:OAuth2 RFC6749中文翻譯
OAuth2.0在安全性方面做了比較大的提高,簡單來說OAuth2.0就是一種授權協議,可以用來授權,隨意點個網站,如圖這種網站,用戶不想注冊,就可以用微信、支付寶登錄,就是場景是很常見的,也是OAuth2.0的應用
二、OAuth2.0原理
OAuth2.0是一種授權機制,正常情況,不使用OAuth2.0等授權機制的系統,客戶端是可以直接訪問資源服務器的資源的,為了用戶安全訪問數據,在訪問中間添加了Access Token機制。客戶端需要攜帶Access Token去訪問受到保護的資源。所以OAuth2.0確保了資源不被惡意客戶端訪問,從而提高了系統的安全性。
2.1 OAuth2.0流程圖
引用官方圖片介紹OAuth2.0總體流程:
- (A)客戶端向從資源所有者請求授權。
- (B)客戶端收到授權許可,資源所有者給客戶端頒發授權許可(比如授權碼code)
- (C)客戶端與授權服務器進行身份認證並出示授權許可(比如授權碼code)請求訪問令牌。
- (D)授權服務器驗證客戶端身份並驗證授權許可,若有效則頒發訪問令牌(accept token)。
- (E)客戶端從資源服務器請求受保護資源並出示訪問令牌(accept token)進行身份驗證。
- (F)資源服務器驗證訪問令牌(accept token),若有效則滿足該請求。
三、 OAuth2.0的角色
OAuth2.0定義如下角色:
- 資源所有者(Resource Owner): 能夠許可受保護資源訪問權限的實體。當資源所有者是個人時,它作為最終用戶被提及。
- 用戶代理(User Agent): 指的的資源擁有者授權的一些渠道。一般指的是瀏覽器、APP
- 客戶端(Client) 使用資源所有者的授權代表資源所有者發起對受保護資源的請求的應用程序。術語“客戶端”並非特指任何特定的的實現特點(例如:應用程序是否在服務器、台式機或其他設備上執行)。
- 授權服務器(Authorization Server): 在成功驗證資源所有者且獲得授權后頒發訪問令牌給客戶端的服務器。
授權服務器和資源服務器之間的交互超出了本規范的范圍。授權服務器可以和資源服務器是同一台服務器,也可以是分離的個體。一個授權服務器可以頒發被多個資源服務器接受的訪問令牌。- 資源服務器(Resource Server): 托管受保護資源的服務器,能夠接收和響應使用訪問令牌對受保護資源的請求。
四、OAuth2.0授權模式
OAuth2.0有4種授權模式:
- 授權碼模式(authorization code)
- 簡化模式(implicit)
- 密碼模式(resource owner password credentials)
- 客戶端模式(client credentials)
其中最常用的是授權碼模式,4種授權模式的詳細介紹可以參考阮一峰老師的:OAuth 2.0 的四種方式
4.1 授權碼模式(authorization code)
授權碼(authorization code)方式,指的是第三方應用先申請一個授權碼,然后再用該碼獲取令牌。
官網圖片:
從調接口方面,簡單來說:
-
第一步:獲取code:
eg:oauthServer+"/oauth/authorize?client_id="+clientId+"&response_type=code&redirect_uri="+redirectUrl+"&scope=all"
如果沒有登錄,則會跳轉到統一身份認證登錄頁面。如果用戶登錄了,調用接口后,會重定向到redirect_uri,授權碼會作為它的參數 -
第二步:獲取access_token
eg:oauthServer+"/oauth/token?code="+code+"&grant_type=authorization_code&client_secret="+clientSecret+"&redirect_uri="+redirectUri+"&client_id="+clientId
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODk1MzQ5NzMsInVzZXJfbmFtZSI6Im5pY2t5IiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9hZG1pbiJdLCJqdGkiOiJmMjM0M2Q0NC1hODViLTQyOGYtOWE1ZS1iNTE4NTAwNTM5ODgiLCJjbGllbnRfaWQiOiJvYSIsInNjb3BlIjpbImFsbCJdfQ.LWkN2gC2dBrGTn5uSPzfdW6yRj7jhlX87EE8scY02hI",
"token_type": "bearer",
"expires_in": 59,
"scope": "all",
"user_name": "nicky",
"jti": "f2343d44-a85b-428f-9a5e-b51850053988"
}
- 第三步:訪問系統資源,此時統一認證服務會根據該認證客戶端權限信息判斷,決定是否返回信息。
訪問:http://localhost:8084/api/userinfo?access_token=${accept_token}
4.2 簡化模式(implicit grant type)
簡化模式(implicit grant type)不通過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"授權碼"這個步驟,因此稱簡化模式
從調接口方面,簡單來說:
- 第一步:訪問授權,要傳client_id:客戶端id,redirect_uri:重定向uri,response_type為token,scope是授權范圍,state是其它自定義參數
- 第二步:授權通過,會重定向到redirect_uri,access_token碼會作為它的參數
- 第三步:拿到acceptToken之后,就可以直接訪問資源
http://localhost:8084/api/userinfo?access_token=${accept_token}
4.3 密碼模式(resource owner password credentials)
密碼模式中,用戶向客戶端提供自己的用戶名和密碼,這通常用在用戶對客戶端高度信任的情況
從調接口方面,簡單來說:
- 第一步:直接傳username,password獲取token
- 第二步:拿到acceptToken之后,就可以直接訪問資源
http://localhost:8084/api/userinfo?access_token=${accept_token}
4.4 客戶端模式(client credentials)
客戶端模式(client credentials)適用於沒有前端的命令行應用,即在命令行下請求令牌
從調接口方面,簡單來說:
-
第一步: 獲取token
http://localhost:8888/oauth/token?client_id=cms&client_secret=123&grant_type=client_credentials&scope=all -
第二步:拿到acceptToken之后,就可以直接訪問資源
http://localhost:8084/api/userinfo?access_token=${accept_token}
學習必要的理論知識后,還是實踐一下才能明白整個流程,詳情參考我OAuth2.0系列博客專欄:OAuth2.0系列博客,SpringBoot的參考我系列博客專欄:SpringBoot系列博客