理解OAuth2


Oatuh2用来做什么

有这样一种场景,一个用户(假设是QQ),希望让一个第三方的应用(比如说某个论坛),能够得到关于自身的一些信息(唯一用户标识,比如说QQ号,用户个人信息,比如说是一些基础资料,昵称和头像等)。但是在获得这些资料的同时,却也不能提供用户名和密码之类的验证信息。比如说用户不可能将自身的用户名和密码给第三方让第三方到用户中心之类的地方去获取信息。要达到这样的结果肯定有许多的实现方式。而Oatuh2就是实现上述目标的一种规范,或者说是具体实现的指导方案。

Oauth2具体做法

首先来了解下Oatuh2中的几个名字,方便下文的阐述。

  1. Third-party application: 第三方应用
  2. Resource Owner: 资源持有者,一般就是用户自身
  3. Authorization server: 认证服务器
  4. Resource server: 资源服务器,即具体资源的存储方。与认证服务器是不同的逻辑节点,但是在物理上,双方是可以在一起的
  5. User Agent: 用户代理,一般就是指的浏览器
  6. Http Service: 服务提供者,也就是持有Resource Server的存在方。可以理解为类似QQ,或者微信这样具备用户信息的服务者。

Oauth2的作用就是让第三方应用在用户(资源持有者)授权的情况下,通过认证服务器的认证,从而安全的在资源服务器上获得对应的用户资源的流程指导。

Oauth2的流程

Oauth2,根据RFC6749文档,大致的流程如下图所示

上图中的client就是第三方应用。可以看到,Oauth的大致思路是一个线性的流程。

  1. 第三方应用向资源持有者请求获取资源
  2. 资源持有者授权给予第三方应用一个许可
  3. 第三方应用将该许可给予认证服务器进行认证,如果认证成功,返回一个Access Token
  4. 第三方应用使用该access token到资源服务器处获取该access token对应的资源(也就是第一步中资源持有者自身的资源)

在上面的这个流程中,其中第二步,资源持有者如何授权给予第三方应用一个许可就是最为关键的地方。其中RFC6749文档给出4种第三方取得授权许可的方式。

  1. 授权码模式
  2. 简化模式
  3. 密码模式
  4. 客户端模式

其中授权码模式是步骤流程最为详细严谨的一种模式。而网络上大部分的第三方Oauth2实现都是基于授权码模式的。本文也是主要讲解授权码模式中的相关流程性问题。至于其他的三种模式,读者可以自行参看RFC6749文档。

授权码模式

授权码模式的流程如下图所示

下面来分别讲解其中的几个点

第三方引导用户跳转至认证服务器的授权页面

在引导跳转的时候需要携带如下的几个参数

  1. response_type:授权类型。授权码模式下,就固定为code
  2. app_id:第三方应用的标识id。
  3. redirect_uri:重定向uri,也就是在授权成功后认证服务器让用户重定向的地址。一般而言也就是当前用户在第三方应用中最初的请求地址
  4. scope:授权范围。可选内容,可以根据第三方应用和实现方的要求自行制定合适的值。
  5. state:透明的验证参数。RFC6749文档推荐认证服务器在重定向的时候应该原封不同的返还这个参数。注意,该参数严格来说应该是一个必须参数。用来防止CSRF攻击。也就是说用于让第三方服务器验证重定向回来的uri的确是认证服务器的行为而不是其他的攻击者伪造的。一般来说跳转到认证服务器的授权页面是走的https,但是认证服务器重定向到回调地址的时候可能走的就是http。此时code存在泄漏以及url存在被伪造的风险。那么第三方应用必须要有办法验证该回调是否的确由认证服务器发起,并且的确是之前自己的授权请求导致的回调。做法其实也不复杂,就是在session中保存一个随机值,作为state参数。认证服务器回调的时候带上该state参数,第三方应用验证该参数是否与自己session中的state参数值一致即可。如果认证的授权页面不是https加密的,那么在发出请求的时候,认证state参数可能会被窃取。那么这个时候还有另外一种做法。也就是第三方应用发送的是加密后的state参数,而认证服务器重定向的时候携带的是解密后的state参数。第三方应用只要在session中判断解密后的值是否与session的一致,也可以达到防止攻击的目的。这样,授权页面也就是可以走在普通的http之中了。

用户选择是否给予授权

这一步是一个用户行为。目前基本的做法都是让用户在授权页面上输入用户名和密码。为了保证安全性,这个页面需要由https来进行保护。当然,如果有其他的方式来保证用户名密码,以及认证的state参数不会泄露也是可以的。如果用户输入正确的用户名和密码,一般就确认为用户给予授权。

认证服务器生成code并且让用户重定向至指定的url

如果用户给予授权,则认证服务器需要生成一个唯一的授权码code。该code的时效性应该比较短,在5分钟以内比较合适。并且该code只能使用一次,下次就会失效。同时,该code与客户端的id,redirect-uri参数是一一对应的关系。认证服务器此时应该让用户重定向至一开始指定的redirect_uri。携带上state和code参数

第三方应用使用code到认证服务器处兑换令牌access token

第三方应用在验证过state参数的正确性后,接着就可以使用code到认证服务器处换取token。这一步,第三方应用需要携带上的参数有

  1. code:就是认证服务器给予的code参数
  2. appid:客户端的唯一标识
  3. redirect_uri:也就是第一步请求中的重定向参数。因为code实际上是与appid和redirect_uri一一对应的。所以用code换取令牌的时候也要携带上这两个参数
  4. grant_type: 授权模式,这里固定为"authorization_code"
  5. appkey:用于验证应用的身份。appid和appkey可以理解为应用自己的用户名和密码。

oauth2的服务器本身都是走https。所以都可以直接明文传输不需要考虑安全性问题。不过如果不是http的,也可以直接参数用户名密码登录的方式,就是给appkey进行md5运算。
关于为何不直接传递accesstoken的问题,是基于安全考虑。因为认证服务器是基于Https,而第三方应用可以是http的。如果在回调的时候直接带上accesstoken,就存在着泄露的问题。

认证服务器返回accesstoken

认证服务器在验证过参数的合法性后,生成一个全局唯一的token,并且返回给第三方应用。返回的内容采用json表示,返回的参数主要有

  1. access_token: 用于获取对应资源的令牌
  2. expires_time: 该令牌的有效期
  3. reflesh_token: 用户获取新的accesstoekn的token。由于accesstoken的有效期比较短,一旦失效,用户需要再走上面的流程是比较繁琐的。为了提升用户体验,可以使用reflesh_token来获取新的accesstoken。不过这个做法,已经有不同的实现方将这个返回参数去掉了。因为实际上reflesh_token也就意味着accesstoekn是永久有效的了。那和直接延长accesstoken的有效期也没有直接区别了。

文章原创首发于公众号:林斌说Java,转载请注明来源,谢谢。

欢迎扫码关注

理解OAuth2的更多相关文章

  1. 程序员的自我救赎---3.1:理解Oauth2.0

    <前言> (一) Winner2.0 框架基础分析 (二)PLSQL报表系统 (三)SSO单点登录 (四) 短信中心与消息中心 (五)钱包系统 (六)GPU支付中心 (七)权限系统 (八) ...

  2. 深入理解OAuth2.0 XSS CSRF CORS 原理

    基于Token的WEB后台认证机制 http://www.cnblogs.com/xiekeli/p/5607107.html 深入理解OAuth2.0协议http://blog.csdn.net/s ...

  3. 深入理解OAuth2.0协议

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...

  4. 帮你深入理解OAuth2.0协议

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...

  5. 深入理解OAuth2.0

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...

  6. 理解 OAuth2.0

    文章转载于阮一峰老师的博客:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 参考文章:https://learnku.com/article ...

  7. (转)帮你深入理解OAuth2.0协议

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题.豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒店 ...

  8. 问题:OAuth2.0;结果:帮你深入理解OAuth2.0协议

    1. 引言 如果你开车去酒店赴宴,你经常会苦于找不到停车位而耽误很多时间.是否有好办法可以避免这个问题呢?有的,听说有一些豪车的车主就不担心这个问题. 豪车一般配备两种钥匙:主钥匙和泊车钥匙.当你到酒 ...

  9. 微信公共服务平台开发(.Net 的实现)12-------网页授权(上 :更加深入理解OAuth2.0 )

    我们首先来认识一下OAuth协议吧,这个东西很早就听说过,总觉得离我很远(我的项目用不到这些),但是最近不得不学习一下了.我在网上找了一些解释,认为解释的最好的是这样说的(出处:http://hi.b ...

随机推荐

  1. python基础-并发编程part01

    并发编程 操作系统发展史 穿孔卡片 读取数据速度特别慢,CPU利用率极低 单用户使用 批处理 读取数据速度特别慢,CPU利用率极低 联机使用 脱机批处理(现代操作系统的设计原理) 读取数据速度提高 C ...

  2. 在jsp页面中设置中序号

    首先要使用<c>标签的话需要先引入下面这句话: <%@ taglib prefix="c" uri="http://Java.sun.com/jsp/j ...

  3. ASP.NET Core3.X 终端中间件转换为端点路由运行

    引言 前几天.NET Core3.1发布,于是我把公司一个基础通用系统升级了,同时删除了几个基础模块当然这几个基础模块与.NET Core3.1无关,其中包括了支付模块,升级完后静文(同事)问我你把支 ...

  4. python3.6异步IO包asyncio部分核心源码思路梳理

    关于python异步编程的演进过程,两篇文章阐述得妥妥当当,明明白白. 中文资料:https://mp.weixin.qq.com/s?__biz=MzIxMjY5NTE0MA==&mid=2 ...

  5. ubuntu部署.Net Core3.1(Nginx+pm2)

    前言 虽然.NetCore已经出来很久了,但是很多初学者还是不会在linux部署.所以写一篇初学者在ubuntu下部署Core的全过程,大佬请无视. 环境搭建 ubuntu18.04 NetCore3 ...

  6. Apache Maven从入门到升天

    喜欢就点个赞呗! GitHub项目JavaHouse同步收录 1 引入 在日常 Java 开发中,Maven 应该是必不可少的一个工具了,当然也有人使用 Gradle 的.那么 Maven 究竟是个啥 ...

  7. Solr单机配置详解

    Solr 单机版安装 安装环境 安装 jdk:JDK 版本: jdk-8u11-linux-x64.tar.gz 环境变量配置; export JAVA_HOME=/usr/local/jdk exp ...

  8. GZIP怎么运用在.NET MVC 简单实现

    ZIP压缩其实就是将网页内容压缩,减少HTML代码网络传输的代价,来提高Web性能. 这个请求的过程解释一下: 1:客户端Request请求.Http_header中会根据相应的浏览器发送相应的编码规 ...

  9. POJ 1651 Mulitiplication Puzzle

    The multiplication puzzle is played with a row of cards, each containing a single positive integer. ...

  10. 关于直线,V形线,Z形线,M形线分割平面的总结

    一:N条直线分割平面 假设,x条线能将平面分为f(x)份,这对于份f(n) 第n条线,和其他n-1条线都有交点时,增加量最大,为n; 则: f(n)=f(n-1)+n; 有f(0)=1:得到:n 条直 ...