为什么会出现OAuth?
授权机制,用于授权第三方应用,获取用户数据, 第三方应用无需用户输入账号密码即可获取访问用户信息资源服务器的权限。
OAuth1.0和OAuth2.0的区别
1.0缺点:1.0中使用的是http协议,容易遭受中间人攻击,伪造回调地址,拿到用户访问令牌。
1.0a中改善了这一点,增加了签名过程攻击者无法伪造回调地址,无法拿到用户访问令牌,但是签名过程增加了复杂度,且实用性不高。
2.0改进:
- 去掉签名,使用SSL(https)保证安全性。
- 所有的token不再有对应的secret,签名过程简洁,这也直接导致2.0不兼容老版本。
- 能更好的支持不是基于浏览器的应用。
- 令牌是短命的,且有刷新令牌的机制。
OAuth2的四种授权模式
授权码模式
- 授权流程如下图所示:授权码模式是功能最完整,授权流程最严密的授权模式,通常运用在公网的开放平台里。
- 授权过程中,有几个角色需要定义定义,授权的过程是用户、被授权的服务、授权服务器、资源服务器,被授权的服务相对于授权服务来说就是客户端(这里包含被授权服务的前端和后台两个部分),在较大的公司会讲究职责单一,那么认证服务器和资源服务器就是两个不同的系统,认证服务器专门用户授权,资源服务器用户保存用户信息。而一般较小企业可能这两个服务器就合并在一起。
所以上边所提到的和下图所展示的角色对应关系就是:
- 用户-资源拥有者(Resource Owner)
- 被授权服务-客户端(Client)
- 认证服务器-认证服务器(Authorization Server)
- 资源服务器-资源服务器(Resource Server)
授权码模式的流程大概分为以下几个步骤:
1.用户访问客户端,客户端将重定向到认证服务器。(重定向给认证服务器时,会提前传递一个重定向的uri,用户用户授权后,将code传递回去)。
2.用户选择是否授权给客户端。
3.用户选择授权,则认证服务器将重定向到客户端提前准备的重定向uri,上边步骤2提到的,并附上一个code(授权码)。
4.客户端收到code,附上早先的重定向uri和code,请求认证服务器申请令牌,这一步是在后台实现的,对用户不可见。
5.认证服务器收到授权码和重定向uri之后,校验无误,发送访问令牌和刷新令牌。
6.客户端携带访问令牌,去资源服务器,获取用户数据。
根据微信开放平台的授权过程进行举例说明
微信开放平台的授权流程如上图
我们授权访问流程如下:
1.前端请求/authonization/weixin接口,该接口重定向到微信授权认证页面: https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 并且传入重定向uriREDIRECT_URI
2.用户扫码,并在手机端确认授权登录,微信服务端生成授权码code,重定向到REDIRECT_URI,并带上code。REDIRECT_URI?code=CODE&state=STATE。
3.重定向接口中,拿到授权码,根绝在微信开放平台申请的appid和appsecret申请令牌,这步骤在后端接口操作,对前端不可见。
拿到访问令牌后,即可获取该用户的基本信息。
简化授权模式
简化授权模式这种方式,允许直接向前端颁发令牌,这种方式没有授权码的步骤
1.用户访问客户端,客户端将用户重定向到认证服务器,并附上重定向uri.
https://b.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
2.等待用户授权
3.用户授权通过后,认证服务器重定向到客户端的uri并拼接认证令牌到uri的锚点
密码模式
密码模式的认证方式是若你高度信任某个应用,你就可以告诉他你的账号密码,该应用就是用你的账号密码申请令牌。
这种方式的步骤是:
1.客户端要求用户提供在资源服务器的账号密码。
2.用户提供账号密码
3.客户端那用户的账号密码向认证服务器请求令牌。
4.认证服务器拿到账号密码经过认证后,颁发访问令牌,这一步无需跳转,认证服务器以json字符串的方式进行将令牌返回。
这种方式需要用户给出自己的账号密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况下,而且必须是高度信任的应用。
凭证式(客户端模式)
适用于没有前端应用,即在命令行下请求令牌。
1.客户端在命令行向认证服务器发出请求
2.认证服务器认证客户端身份以后,直接返回令牌。
这种情况给出的令牌是提供给第三方应用的,不是针对用户的,所以可能多个用户共享一个令牌。
总结:
授权码模式,更安全授权流程更严密,授权码有有效期10分钟并且只能使用一次,即使授权码被截获,但是授权码是和客户端进行绑定的,所以被截获后也无法直接获取到用户令牌。
简化授权模式,令牌直接办法给了浏览器,不安全,如何防止攻击,尽量使用htts请求,并且用户令牌被放在锚点而不是querystring,跳转时不会被转发到服务器。
密码模式,直接使用用户账号密码获取授权,必须是用户高度信任的应用并且是其他授权方式都无法使用的情况,去使用的一种授权方式。
凭证模式(客户端模式):针对于第三方应用而不是个人用户。
为什么授权方式后边添加state就能防止CSRF(跨站请求伪造)攻击,CSRF攻击是利用网站对网页浏览器的新任,攻击者主要做的就是欺骗用户浏览器,以用户的名义进行操作,state参数能标记这是来自哪个网站的请求,攻击者拿不到这个参数因此可以避免CSRF攻击。
文章总结自:
阮一峰:http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
Coding10:http://www.coding10.com/section/oauth2-brief-roles-in-system
https://blog.youkuaiyun.com/ivolcano/article/details/90414175