文章目录
  1. 1. 参考文献
  2. 2. 理解体会
    1. 2.1. 用户及客户端视角
    2. 2.2. 其他问题
  3. 3. 进阶
    1. 3.1. 客户服务器如何取得资源

引言:最近在SHUhelper的Roadmap里看到OAUTH2的TODO,想起前几天才主动向朱老师提出帮学校重构统一身份认证的事情,于是决定了解了解。


参考文献

  1. 理解OAuth 2.0 - 阮一峰
  2. OAuth 2 深入介绍
  3. CSRF背景与介绍
  4. OAuth2.0忽略state参数引发的CSRF漏洞
  5. OAuth 2.0 - jenkov.com
  6. rfc6749 - IETF

理解体会

本文只关注授权码模式(authorization code),这里假设你理解什么是前端和后端,并且有一定的网络知识基础。下文按我自己的理解组织。

用户及客户端视角

在阮老师的文献【记为原文】中,客户端即云冲印网站的后端,认证服务器即谷歌登录OAuth授权服务器。

  1. 用户首先访问云冲印网站,点击获取谷歌相册照片,向后端发送该请求 [请求1] ,云冲印后端检测用户未授权谷歌信息,身份无效,则开始准备OAuth认证。【对应原文步骤A】

    在该请求1中,首先后端生成随机的字符串序列state,以及redirect_uri,redirect_uri通常为后端接口地址。随后后端返回302重定向,重定向到OAuth认证地址,query参数为response_type client_id redirect_uri scope state,其中client_id即云冲印这个客户端标识,redirect_uri和scope可选,请求1结束。

  2. 客户端在OAuth页面输入用户名密码或其他认证方式登录,以同意授权。【对应原文步骤B】

  3. 认证服务器确认用户身份无误后,为用户302重定向至redirect_uri [请求2] ,并且返回授权码code,以及请求1中提到的相同的state。【步骤C】

    在该请求2中,云冲印后端拿到认证服务器颁发的授权码code,以及回执的state,对比之前随机生成的state,判断是否一致,以防CSRF攻击 [CSRF介绍见参考文献3,state如何防止CSRF见参考文献4]

  4. 在该请求2中,后端向认证服务器发送申请令牌的HTTP请求 [请求3] ,包含参数grant_type code redirect_uri client_id client_secret,其中client_idclient_secret可被其他Authorization认证方式代替(如jwt)。在这一步中,后端向认证服务器发出的请求必须是https的,否则有client_id和client_secret被拦截的风险。【步骤D】

  5. 当认证服务器收到请求3后,验证code、client_id以及client_secret,颁发access_token。【步骤E】 [注:为什么传入redirect_uri见下面的其他问题3]

拿到请求3的response后,后端可使用获得的access_token调用资源服务器的API。

如果OAuth是用来做第三方登录或注册,那么在请求2的结束,需要给用户签发一个cookie,并且重定向到云冲印网站登录成功的页面。其实这一步的最后怎么做,完全取决于你要用这波OAuth做什么。

[注:上面所述的请求1、请求2、…、请求n只阐明了比较重要的请求,而非所有请求]

其他问题

  1. 为什么步骤C中,认证服务器要传回code,而不是直接传回access_token?

    答:不是所有站点都支持https,如果在http下直接传回access_token,该access_token可能会被窃取。因此传回code,后端使用code+client_id+client_secret(或其他认证方式如jwt)才可获取到资源。这是一种双重认证。

  2. 为什么步骤C中不要忽略state参数?

    见参考文献3。

  3. 为什么步骤D中要发出redirect_uri,有client_id不够吗?

    假设我不传入redirect_uri,并且假设受害client app有一个state漏洞【见参考文献4】。那么我现在有个网站,是做CSRF攻击的,我现在要攻击受害client app的A站账号绑定认证服务。现在用户Tom访问我网站的时候,我做一个跳转到A站认证服务器,参数中client_id是受害client app的client_id,redirect_uri是我自己设置的redirect_uri。用户Tom登录了,当我在redirect_uri收到code的时候,我使用我自己在受害client app的账号的cookie,访问这个redirect_uri,那么由于受害client app没有做state认证,只用code来标识一条A站信息,用户Tom的A站账号就会绑定到我的client app账号上去。

    甚至如果在用户跳转到A站认证服务器时,认证服务器由于发现用户已登录而自动认证成功,那么就可以自动完成这些步骤。

    但是当我在access_token request中传入redirect_uri后,认证服务器核实redirect_uri和code,发现不一致,则驳回access_token request,拒绝掉这种攻击。

    但不意味着有redirect_uri的限制,就可以杜绝所有的CSRF攻击,防止CSRF攻击还是得使用随机state。

进阶

参考文献5讲述了client application、resource server、autorhization server之间具体的工作流程。

客户服务器如何取得资源

Whenever the client application requests access to resources stored on that same resource server, the client application needs to authenticate itself by sending along the client ID and the client secret to the autorhization server.

上图来源见水印。


至此通关!
文章目录
  1. 1. 参考文献
  2. 2. 理解体会
    1. 2.1. 用户及客户端视角
    2. 2.2. 其他问题
  3. 3. 进阶
    1. 3.1. 客户服务器如何取得资源