使用OAuth实现统一登录的安全防范
当使用 OAuth2.0 去实现应用的统一登录验证时,会存在一些安全问题,值得开发者们思考与防范。特指 authorization code
模式。
回顾一下authorization code
授权登录的整个流程:
到 OAuth Provider 注册一个应用,获取 app key(client ID) 和 app secret,并填写回调地址;
client 端引导用户打开统一登录页面,并携带
app key
。用户登录完成后跳转到指定的
redirect_uri
,并返回authorization code
。题外话:implicit 模式貌似可在 step3 直接返回 token
第三方 app 服务端调用
OAuth Provider
获取 token 的 API,通常是/oauth/token
, 携带authorization code
和app key
、app secret
去换取 token.拿到 token 后就算登录成功了
流程:
潜在的安全问题:
中间人攻击
攻击者通过劫持、伪造网络基站等方式监听了你的通信信息。如果使用了明文传输,那么很容易获取到你的账号密码。但是中间人攻击的方式对于 OAuth 来说,最多也只是能够获取到 Authorization code,看起来作用不太大。每个 code 被设计为具有时效性+只能使用一次,且只能搭配 app secret 使用, secret 一般只存在服务端。
重新拼接authorization URL
,替换回调地址
如果开发者没有在 OAuth Provider Center 去设置精确的回调地址,比如使用*
或者http://
,那就容易因为被替换回调地址而泄露了 authorization code
,攻击者在拿到 authorization code 之后,再获取你的 app key(公开的) 和 app select 就可以去替换 token 了。所以也要避免自己的 app secret 泄露,因此一般 app secret 都存储在服务端,换取 token 的流程也应该在 app 的服务端进行,而不在前端。
防范措施:
- redirect URL 应该做精确比配校验
- 不暴露(使用) app secret,比如使用 PKCE
PKCE 是为了防止 authorization code 泄露而设计的
以下是使用 PKCE 增强安全性的步骤
创建随机的 Code Verifier:客户端生成一个随机的 Code Verifier。Code Verifier 是一个随机的、高熵的字符串,可以使用 Base64 URL 编码。
计算 Code Challenge:客户端使用 SHA256 哈希算法计算 Code Verifier 的哈希值,并对哈希值进行 Base64 URL 编码,生成 Code Challenge。
发起授权请求:在授权请求中,客户端将 Code Challenge 和相应的哈希算法(通常为”code_challenge_method=S256”)发送给授权服务器。
授权服务器验证:授权服务器接收到授权请求后,将 Code Challenge 进行验证。如果验证通过,它将返回授权码给客户端。
交换授权码:客户端使用授权码和原始的 Code Verifier 来交换访问令牌。授权服务器会验证 Code Verifier 是否与之前发送的 Code Challenge 匹配。只有匹配的情况下,才会返回访问令牌。