码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 关于OAuth2.0 Authorization Code + PKCE flow在原生客户端(Native App)下集成的一点思考


    Working with Proof Key for Code Exchange (PKCE) - DEV Community

    写在前面#

    前几天看了园友的一篇文章被广泛使用的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#

    img

    (图来自)

    回顾流程和请求

    我这里是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中使用#

    img

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

    👇专注于后端和架构,欢迎扫码关注我的公众号👇
  • 相关阅读:
    单链表的排序操作
    MongoDB~分片数据存储Chunk;其迁移原理、影响,以及避免手段
    【Leetcode刷题Python】高效求递归中函数的调用次数(动态规划方法,顺丰笔试题)
    ctfshow node.js专题
    C#面:switch 表达式可以用什么类型?能用 string 类型吗?
    Spring系列之bean的使用简介说明
    力扣labuladong——一刷day35
    2022年--软件设计师下午题高频考点技巧总结
    Spring 源码(16)Spring Bean的创建过程(7)属性填充
    应用层 ------ HTTP协议
  • 原文地址:https://www.cnblogs.com/xiaxiaolu/p/16042158.html
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号