写在前面

前几天看了园友的一篇文章被广泛使用的OAuth2.0的密码模式已经废了,放弃吧 被再次提起: Implicit Flow Password Grant,均已被标记为Legacy,且OAuth2.1里面已经删除了,目前OAuth2.1只剩三种flow:

  • Authorization Code+ PKCE
  • Client Credentials
  • Device Code

作为完美踩坑ImplicitPassword 两种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 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

  • 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 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

  • 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中使用

PKCE在这篇文章里面已经讲得很清楚了,我简单总结下:

上文我们已经清楚,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_challengecode_challenge_method来发起授权请求,生成关联这两项值的code;
  • 4、用code和code_verifier去换取token;
  • 5、授权服务器返回token,和refresh token(app这个很重要);

我们可以看到,因为我们的code已经关联code_challengecode_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)下集成的一点思考的更多相关文章

  1. [转]OAuth 2.0 - Authorization Code授权方式详解

    本文转自:http://www.cnblogs.com/highend/archive/2012/07/06/oautn2_authorization_code.html I:OAuth 2.0 开发 ...

  2. OAuth 2.0 - Authorization Code授权方式详解

    I:OAuth 2.0 开发前期准备 天上不会自然掉馅饼让你轻松地去访问到人家资源服务器里面的用户数据资源,所以你需要做的前期开发准备工作就是把AppKey, AppSecret取到手 新浪获取传送门 ...

  3. OAuth2.0和企业内部统一登录,token验证方式,OAuth2.0的 Authorization code grant 和 Implicit grant区别

    统一登录是个很多应用系统都要考虑的问题,多个项目的话最好前期进行统一设计,否则后面改造兼容很麻烦: cas认证的方式:新公司都是老项目,用的是cas认证的方式,比较重而且依赖较多,winform的项目 ...

  4. 被广泛使用的OAuth2.0的密码模式已经废了,放弃吧

    最近一直有同学在问,OAuth2密码模式为啥Spring Security还没有实现,就连新的Spring Authorization Server也没有这个玩意儿. 其实这里可以告诉大家,OAuth ...

  5. OAuth2.0学习(1-3)OAuth2.0的参与者和流程

    OAuth(开放授权)是一个开放标准.允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息.而这种授权无需将用户提供用户名和密码提供给该第三方网站. OAuth允许用户提供一个令牌给第 ...

  6. 使用微服务架构思想,设计部署OAuth2.0授权认证框架

    1,授权认证与微服务架构 1.1,由不同团队合作引发的授权认证问题 去年的时候,公司开发一款新产品,但人手不够,将B/S系统的Web开发外包,外包团队使用Vue.js框架,调用我们的WebAPI,但是 ...

  7. OAuth2.0标准类库汇总

    转载官网: https://oauth.net/code/ https://www.w3cschool.cn/oauth2/5ghz1jab.html 服务端类库 .NET .NET DotNetOp ...

  8. API代理网关和OAuth2.0授权认证框架

    API代理网关和OAuth2.0授权认证框架 https://www.cnblogs.com/bluedoctor/p/8967951.html 1,授权认证与微服务架构 1.1,由不同团队合作引发的 ...

  9. 基于OAuth2.0的统一身份认证中心设计

    1. 引言 公司经历多年发展后,在内部存在多套信息系统,每套信息系统的作用各不相同,每套系统也都拥有自己独立的账号密码权限体系,这时,每个人员都需要记住不同系统的账号密码,人员入职和离职时,人事部门都 ...

随机推荐

  1. 【HDU6687】Rikka with Stable Marriage(Trie树 贪心)

    题目链接 大意 给定\(A,B\)两个数组,让他们进行匹配. 我们称\(A_i\)与\(B_j\)的匹配是稳定的,当且仅当目前所剩元素不存在\(A_x\)或\(B_y\)使得 \(A_i\oplus ...

  2. Solution -「AT 3913」XOR Tree

    \(\mathcal{Description}\)   Link.   给定一棵树,边 \((u,v)\) 有边权 \(w(u,v)\).每次操作可以使一条简单路径上的边权异或任意非负整数.求最少的操 ...

  3. Solution -「JOISC 2019」「LOJ #3036」指定城市

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个结点的树,双向边权不相同.\(q\) 次询问,每次询问在树上标记 \(e\) 个点,标记的价值为所有趋 ...

  4. JavaScript函数式编程(纯函数、柯里化以及组合函数)

    JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 函数式编程(Functional Programming),又称为泛函编程,是一种编程范式.早在很久以前就提出了函数式编程这个概念了 ...

  5. JAVA8学习——新的时间日期API&Java8总结

    JAVA8-时间日期API java8之前用过的时间日期类. Date Calendar SimpleDateFormat 有很多致命的问题. 1.没有时区概念 2.计算麻烦,实现困难 3.类是可变的 ...

  6. 轩辕展览-VR虚拟展厅设计如何实现全景漫游功能

    什么是在线3d漫游?如何在VR虚拟展厅设计之中实现3d漫游功能?让我们来分享3dVR虚拟展厅的在线漫游. 实际上,在线3d漫游就是通过3d仿真场景,使用鼠标和键盘在虚拟空间之中自由漫游,它可以从高空俯 ...

  7. kali linux 出现 E: 您在 /var/cache/apt/archives/ 上没有足够的可用空间。

    问题: E: 您在 /var/cache/apt/archives/ 上没有足够的可用空间. 软链接到HOME下的一个目录即可,home下新建debs文件夹: 在某个空间大的分区建立一个目录,然后把/ ...

  8. 思迈特软件Smartbi的特色功能有哪些?

    Smartbi产品价值: 从最终用户角度 管理层:KPI监控.风险预警.绩效考核.大屏展示,移动分析,实现经营管理主题(财务.销售.人事.绩效等)的直观监控,为经营管理提供决策支持 分析人员:拖拽式的 ...

  9. SQL Server Cross/Outer Apply

    SQL Server2005引入了APPLY运算符,它非常像连接子句,它允许两个表达式直接进行连接,即将左/外部表达式和右/内部表达式连接起来. CROSS APPLY(类比inner join)和O ...

  10. Mysql基础学习第二天

    Mysql基础学习第二天 函数 函数:是指一段可以直接被另一段程序调用的程序或代码. 字符串函数 数值函数 日期函数 流程函数 字符串函数 MySQL内置很多字符串函数,常用的几个如下: 函数 功能 ...