模式|OAuth 2.0 扩展协议之 PKCE

微软中国MSDN 点击上方 蓝字关注我们
大家好 , 我是本期的实验室研究员——等天黑 。 今天我们的研究对象是OAuth扩展协议PKCE,其中在OAuth 2.1草案中, 推荐使用Authorization Code + PKCE的授权模式, PKCE为什么如此重要? 接下来就让我们一起到实验室中一探究竟吧!
微软MVP实验室研究员

模式|OAuth 2.0 扩展协议之 PKCE
文章图片

等天黑
开源爱好者 , 技术博客博主, 运营有公众号:全球技术精选 , 目前技术研究方向是 .NET, 微服务, 云原生 。
前言
PKCE全称是Proof Key for Code Exchange , 在2015年发布 , 它是OAuth 2.0核心的一个扩展协议 , 所以可以和现有的授权模式结合使用 , 比如Authorization Code + PKCE , 这也是最佳实践 , PKCE最初是为移动设备应用和本地应用创建的 , 主要是为了减少公共客户端的授权码拦截攻击 。
在最新的OAuth 2.1规范中(草案) , 推荐所有客户端都使用 PKCE ,而不仅仅是公共客户端 , 并且移除了Implicit隐式和Password模式 , 那之前使用这两种模式的客户端怎么办? 是的 , 您现在都可以尝试使用Authorization Code + PKCE的授权模式 。 那 PKCE为什么有这种魔力呢? 实际上它的原理是客户端提供一个自创建的证明给授权服务器 , 授权服务器通过它来验证客户端 , 把访问令牌(access_token) 颁发给真实的客户端而不是伪造的 。
客户端类型
上面说到了PKCE主要是为了减少公共客户端的授权码拦截攻击 , 那就有必要介绍下两种客户端类型了 。
OAuth 2.0 核心规范定义了两种客户端类型 , confidential机密的 , 和public公开的 , 区分这两种类型的方法是 , 判断这个客户端是否有能力维护自己的机密性凭据client_secret 。

  • confidential
    对于一个普通的web站点来说 , 虽然用户可以访问到前端页面 , 但是数据都来自服务器的后端api服务 , 前端只是获取授权码code , 通过code换取access_token这一步是在后端的api完成的 , 由于是内部的服务器 , 客户端有能力维护密码或者密钥信息 , 这种是机密的的客户端 。
  • public
    客户端本身没有能力保存密钥信息 , 比如桌面软件 , 手机App , 单页面程序(SPA) , 因为这些应用是发布出去的 , 实际上也就没有安全可言 , 恶意攻击者可以通过反编译等手段查看到客户端的密钥 , 这种是公开的客户端 。
在OAuth 2.0授权码模式(Authorization Code)中 , 客户端通过授权码code向授权服务器获取访问令牌(access_token) 时 , 同时还需要在请求中携带客户端密钥(client_secret) , 授权服务器对其进行验证 , 保证access_token颁发给了合法的客户端 , 对于公开的客户端来说 , 本身就有密钥泄露的风险 , 所以就不能使用常规OAuth 2.0的授权码模式 , 于是就针对这种不能使用client_secret的场景 , 衍生出了Implicit隐式模式 , 这种模式从一开始就是不安全的 。 在经过一段时间之后 , PKCE扩展协议推出 , 就是为了解决公开客户端的授权安全问题 。

推荐阅读