关于OAuth2.0 Authorization Code+PKCE flow在原生客户端(Native App)下集成的思考
寫在前面
前幾天看了園友的一篇文章被廣泛使用的OAuth2.0的密碼模式已經廢了,放棄吧 ?被再次提起:Implicit Flow Password Grant,均已被標記為Legacy,且OAuth2.1里面已經刪除了,目前OAuth2.1只剩三種flow:
Authorization Code+ PKCE
Client Credentials
Device Code
作為完美踩坑Implicit 和 Password 兩種flow的人,有點感慨,特來發表下自己的愚見;
并帶著以下問題:
在SPA(單頁面應用程序Vue等)中不再用Implicit flow,還能用什么?
在Native App和小程序等Public Client中不再用Password flow,還能用什么?
Implicit 和 Password 的問題
以下均為個人理解,不保證全對
Implicit的問題
1、比較容易泄露access_token(下文簡稱token), 比如有的開發者條件不允許,web 服務用http的協議直接上生產(正確是一定要用https);
2、token直接暴露在請求里,如果token權限不控制好的話用戶能輕而易舉調用不該有權限的接口;
解決方案:
改為用 :Authorization Code + PKCE
Password的問題
園友已經說的很清楚了我總結下;
1、最大的問題就是違背了委托授權的原則,比如我的Web服務用微信登錄用的Password flow的話,那意思是需要在我的登錄頁面里面填寫微信的賬號和密碼,這眼見的不可思議和不合理吧;
我個人看法:
雖然目前OAuth2最佳實踐中已經明確要求不能使用這種模式,但是 原有已經使用是這種模式的自有App還是可以接著使用的 沒有問題;因為自有App和自有授權中心沒有需要授權,是一起的;
如果是新開發App呢,還是優先考慮:Authorization Code + PKCE,畢竟Password已經是過時的流程了;
思考Authorization Code+ PKCE在Native App使用的問題
先回顧Authorization code Flow
(圖來自)
回顧流程和請求
我這里是web服務,用的是SPA的客戶端,授權服務用的是IdentityServer4;
假設授權服務是:https://localhost:44356/ 客戶端是:https://localhost:44357/
A、先判斷登錄、未登錄先引導用戶去授權服務器授權(一般是打開授權方登錄頁面);
判斷登錄
https://localhost:44356/connect/authorize?client_id=vuejs_code_client&redirect_uri=https%3A%2F%2Flocalhost%3A44357%2Fcallback.html&response_type=code&scope=openid%20profile%20dataEventRecords&state=10f308dbb5d54c01be3b97c495569e8c&code_challenge=gp1EWoH_KsIdL6sGyohEIR6815PcVmz05V_dYvPbafI&code_challenge_method=S256&response_mode=query
登錄頁面
https://localhost:44356/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dvuejs_code_client%26redirect_uri%3Dhttps%253A%252F%252Flocalhost%253A44357%252Fcallback.html%26response_type%3Dcode%26scope%3Dopenid%2520profile%2520dataEventRecords%26state%3D10f308dbb5d54c01be3b97c495569e8c%26code_challenge%3Dgp1EWoH_KsIdL6sGyohEIR6815PcVmz05V_dYvPbafI%26code_challenge_method%3DS256%26response_mode%3Dquery
C、登錄成功返回Authorization code;
登錄成功回調
https://localhost:44356/connect/authorize/callback?client_id=vuejs_code_client&redirect_uri=https%3A%2F%2Flocalhost%3A44357%2Fcallback.html&response_type=code&scope=openid%20profile%20dataEventRecords&state=10f308dbb5d54c01be3b97c495569e8c&code_challenge=gp1EWoH_KsIdL6sGyohEIR6815PcVmz05V_dYvPbafI&code_challenge_method=S256&response_mode=query
https://localhost:44357/callback.html?code=C0EF4B31E9F67481019DC51ED3F393264973027E0275644915314ED25F0F95B7&scope=openid%20profile%20dataEventRecords&state=10f308dbb5d54c01be3b97c495569e8c&session_state=j4dyIjlHucHYEHMrli0nBisCinR9Iq9gncp3khniF58.6A5CBF9592729E89570BE9FAC8A962DF
D、通過code去授權中心token endpoint換取token;
post 請求 https://localhost:44356/connect/token
ok,以上流程后拿到token后面的請求Resource Owner就沒問題了。
Authorization code Flow在Native App中使用有何問題
首先是Authorization code流程里面的,code參數傳遞通過重定向的方式,在原生App里一般這樣重定向一般有兩種方式:
1、是綁定URL Scheme通過類似app-name://?code=的方法把code傳遞給原生客戶端;
2、在本地起個HTTP服務器通過http://localhost:port/?code=的方法監聽code
這兩種方式都有被第三方惡意應用占用URL Scheme或者localhost端口截取code的風險。
另一個問題是,Authorization code code換取token的時候需要app_secret這些;
所以引出我們的PKCE流程;
Authorization Code**+ **PKCE在Native App中使用
imgPKCE在這篇文章里面已經講得很清楚了,我簡單總結下:
上文我們已經清楚,Authorization code(簡稱code)流程里面的,code傳遞給原生App的兩種方式都不安全,那么引出PKCE的概念:
PKCE
全稱Proof Key for Code Exchange,直譯:用一個Proof key來做Code交換;
解決的問題是,既然你可以攔截我的Authorization code,那我再加一個我有,你沒有的參數(等于是票據、驗證憑據)做code交換條件就行;
PKCE步驟為:
1、先隨機生成一串字符串叫code_verifier;
2、用code_challenge_method方法(sha256等)把code_verifier加密成code_challenge;
3、把code_challenge和code_challenge_method來發起授權請求,生成關聯這兩項值的code;
4、用code和code_verifier去換取token;
5、授權服務器返回token,和refresh token(app這個很重要);
我們可以看到,因為我們的code已經關聯code_challenge和code_challenge_method,即時攻擊者攔截了也沒用了,因為你沒有code_verifier,你同樣換不到token;;
最后,可以看到整個PKCE流程設計精妙,已經解決了Code傳參問題;
總結
有了PKCE, 在Native App中使用Code傳參的話直接用原先的方式:
1、是綁定URL Scheme通過類似app-name://?code=的方法把code傳遞給原生客戶端;
2、在本地起個HTTP服務器通過http://localhost:port/?code=的方法監聽code
傳遞code就行;
另外還有一種方式,直接在Native App里面嵌入Webview來傳遞,在攜帶code重定向這個步驟,攔截重定向url,獲取code,換取token;
現在我看到很多App都是這樣做的;
水完,over.
參考
https://www.cnblogs.com/felordcn/p/16011138.html
https://www.cnblogs.com/myshowtime/p/15555538.html
https://medium.com/oauth-2/why-you-should-stop-using-the-oauth-implicit-grant-2436ced1c926
文章博客園地址請點擊“閱讀原文”
不給我點個贊再走嗎~
總結
以上是生活随笔為你收集整理的关于OAuth2.0 Authorization Code+PKCE flow在原生客户端(Native App)下集成的思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云上“炼”码兵器 GitHub Code
- 下一篇: 都说不要装箱,那装箱到底带来了什么开销?