前几天看了园友的一篇文章被广泛使用的OAuth2.0的密码模式已经废了,放弃吧 被再次提起: Implicit Flow Password Grant,均已被标记为Legacy
,且OAuth2.1里面已经删除了,目前OAuth2.1只剩三种flow:
作为完美踩坑Implicit
和 Password
两种flow的人,有点感慨,特来发表下自己的愚见;
并带着以下问题:
以下均为个人理解,不保证全对
解决方案:
改为用 :Authorization Code + PKCE
园友已经说的很清楚了我总结下;
我个人看法:
虽然目前OAuth2最佳实践中已经明确要求不能使用这种模式,但是 原有已经使用是这种模式的自有App还是可以接着使用的 没有问题;因为自有App和自有授权中心没有需要授权,是一起的;
如果是新开发App呢,还是优先考虑:Authorization Code + PKCE,毕竟Password已经是过时的流程了;
(图来自)
回顾流程和请求
我这里是web服务,用的是SPA的客户端,授权服务用的是IdentityServer4;
假设授权服务是:https://localhost:44356/ 客户端是:https://localhost:44357/
判断登录 https://localhost:44356/connect/authorize?client_id=vuejs_code_client&redirect_uri=https%3A%2F%2Flocalhost%3A44357%2Fcallback.html&response_type=code&scope=openid profile dataEventRecords&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
登录成功回调 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 profile dataEventRecords&state=10f308dbb5d54c01be3b97c495569e8c&code_challenge=gp1EWoH_KsIdL6sGyohEIR6815PcVmz05V_dYvPbafI&code_challenge_method=S256&response_mode=query https://localhost:44357/callback.html?code=C0EF4B31E9F67481019DC51ED3F393264973027E0275644915314ED25F0F95B7&scope=openid profile dataEventRecords&state=10f308dbb5d54c01be3b97c495569e8c&session_state=j4dyIjlHucHYEHMrli0nBisCinR9Iq9gncp3khniF58.6A5CBF9592729E89570BE9FAC8A962DF
post 请求 https://localhost:44356/connect/token
ok,以上流程后拿到token后面的请求Resource Owner就没问题了。
首先是Authorization code流程里面的,code参数传递通过重定向的方式,在原生App里一般这样重定向一般有两种方式:
这两种方式都有被第三方恶意应用占用URL Scheme或者localhost端口截取code的风险。
另一个问题是,Authorization code code换取token的时候需要app_secret这些;
所以引出我们的PKCE流程;
PKCE在这篇文章里面已经讲得很清楚了,我简单总结下:
上文我们已经清楚,Authorization code(简称code)流程里面的,code传递给原生App的两种方式都不安全,那么引出PKCE的概念:
PKCE
全称Proof Key for Code Exchange,直译:用一个Proof key来做Code交换;
解决的问题是,既然你可以拦截我的Authorization code,那我再加一个我有,你没有的参数(等于是票据、验证凭据)做code交换条件就行;
PKCE步骤为:
code_verifier
;code_challenge_method
方法(sha256等)把code_verifier
加密成code_challenge
;code_challenge
和code_challenge_method
来发起授权请求,生成关联这两项值的code;code_verifier
去换取token;我们可以看到,因为我们的code已经关联code_challenge
和code_challenge_method
,即时攻击者拦截了也没用了,因为你没有code_verifier
,你同样换不到token;;
最后,可以看到整个PKCE流程设计精妙,已经解决了Code传参问题;
有了PKCE, 在Native App中使用Code传参的话直接用原先的方式:
传递code就行;
另外还有一种方式,直接在Native App里面嵌入Webview来传递,在携带code重定向这个步骤,拦截重定向url,获取code,换取token;
现在我看到很多App都是这样做的;
水完,over.