web:http://oauth.net/2/
rfc:http://tools.ietf.org/html/rfc6749
doc:http://oauth.net/documentation/
code:http://oauth.net/code/

OAuth2.0授权类型

OAuth2.0协议定义了用于获得授权的四种主要授权类型。

Authorization code
标准的Server授权模式,非常适合Server端的Web应用。一旦资源的拥有者授权访问他们的数据之后,他们将会被重定向到Web应用并在URL的查询参数中附带一个授权码(code)。在客户端里,该code用于请求访问令牌(access_token)。并且该令牌交换的过程是两个服务端之前完成的,防止其他人甚至是资源拥有者本人得到该令牌。另外,在该授权模式下可以通过refresh_token来刷新令牌以延长访问授权时间。

Implicit Grant
该模式是所有授权模式中最简单的一种,并为运行于浏览器中的脚本应用做了优化。当用户访问该应用时,服务端会立即生成一个新的访问令牌(access_token)并通过URL的#hash段传回客户端。这时,客户端就可以利用JavaScript等将其取出然后请求API接口。该模式不需要授权码(code),当然也不会提供refresh token以获得长期访问的入口。

Resource Owner Password Credentials
这种模式要求用户提供用户名和密码来交换访问令牌(access_token)。该模式仅用于非常值得信任的用户,例如API提供者本人所写的移动应用。虽然用户也要求提供密码,但并不需要存储在设备上。因为初始验证之后,只需将OAuth的令牌记录下来即可。如果用户希望取消授权,因为其真实密码并没有被记录,因此无需修改密码就可以立即取消授权。token本身也只是得到有限的授权,因此相比最传统的username/password授权,该模式依然更为安全。

Client Credentials
一种基于APP的密钥直接进行授权,因此APP的权限非常大。它适合像数据库或存储服务器这种对API的访问需求

之前做微信公众平台,基本流程参照文档,也没有太注意OAuth太多细节,最近在与携程会员对接,陆陆续续折腾好几天吧,就花了一点时间研究了下OAuth协议,感觉OAuth大行其道路,另外OAuth与OpenID是比较容易混淆的两个东西,OpenID设计的目的趋向与身份校验,OAuth设计的目的是对用户的资源授权。现阶段一般互联网公司应该都支持OAuth2协议,如新浪,阿里,腾讯等,特点是都拥有大量的用户群,来等待其他开发者与第三方应用的接入,如现在比较火爆的微信公众平台。

什么是OAuth2.0

OAuth2.0是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动或桌面应用上存储的私密的资源(如用户个人信息、照片、视频、联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth 2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。
OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。

上面是比较官方的描述,简单些就是OAuth2是由OAuth1.0发展而来,两者不向后兼容,支持多平台设备。可以使用自己的账户与密码授权来让第三方应用在特定的时间内获得用户的资源信息。以新浪围脖为例,比如我习惯用微博登录一些社交网站,这样发现有意思的东西,可以快速分享到微博上,嗯,我经常这么干。按照流程一般先需要用户到新浪上去授权,登录成功后,在知乎上就可以获得微博上的头像与用户基本信息等。

OAuth2授权流程

在讲述OAuth2.0之前先得了解基本授权的基本术语:

资源拥有者(resource owner):能授权访问受保护资源的一个实体,如新浪微博用户 irving;

资源服务器(resource server):存储受保护资源,客户端通过access token请求资源,资源服务器响应受保护资源给客户端;存储着用户irving的微博等信息。

授权服务器(authorization server):成功验证资源拥有者并获取授权之后,授权服务器颁发授权令牌(Access Token)给客户端。

客户端(client:如新浪微博第三方应用,也可以是它自己的官方应用;其本身不存储资源,而是资源拥有者授权通过后,使用它的授权(授权令牌)访问受保护资源,然后客户端把相应的数据展示出来。“客户端”术语不代表任何特定实现(如应用运行在一台服务器、桌面、手机或其他设备)。

+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+

Figure 1: Abstract Protocol Flow

OAuth2授权模式

客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权方式。

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

因为一般授权码的使用的比较多,客户端可能会使用简化模式或客户端模式,我这里只简述授权码模式,授权码流程

+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)

Note: The lines illustrating steps (A), (B), and (C) are broken into
two parts as they pass through the user-agent.

Figure 3: Authorization Code Flow

(A)用户授权访问认证服务器
(B)用户选择是否给予客户端授权

(C)如果给予授权,认证服务器(authorization service)将重定向(http状态码302)到A流程中给予的URL(redirect_uri),同时附上一个授权码(code)

(D)客户端收到授权码(code),向认证服务器(authorization service)申请令牌(发送post请求)。这个过程是在客户端的后台请求上完成的,对用户不可见

(E)认证服务器检查授权码(code)和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)以及失效时间(expires_in)

如新浪的授权流程图:

1、客户端从资源拥有者给予授权

比如我现在使用新浪微博的账户授权登录知乎。

https://api.weibo.com/oauth2/authorize?redirect_uri=http%3A%2F%2Fwww.zhihu.com%2Foauth%2Fauth%2Frequest_sina_token%3Fnext%3D%252Foauth%252Faccount_callback&response_type=code&client_id=3063806388&state=cd8a438eaabbdb6efbbb964edc536648

GET /oauth/auth/sina?next=/oauth/account_callback HTTP/1.1

Host: www.zhihu.com

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://www.zhihu.com/

请求包含以下参数:

  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围如 user,order,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

一般开发一个基于新浪微博app的第三方应用,需要申请appkey和appsecret分别对应OAuth2.0中的client_id与client_secret,可能一些服务端会扩展一些其他的名称,腾讯就是这个干的。

2、用户同意给予客户端授权

分两种情况,如果是没有微博登录成功的会话,就让用户登录,如上图如果之前我已经有了登录成功的会话了,这个时候就让用户确认同意授权(知乎好流氓,直接略了这一步,但是流程还是一样的),我用其他网站的联合登录截了个图如下。

CONNECT api.weibo.com:443 HTTP/1.1

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0

Connection: keep-alive

Connection: keep-alive

Host: api.weibo.com:443

后面我使用Fiddler抓了下包流程还是一样的,还是一样会302跳转,另外发现还使用了socketio,貌似服务端有基于NodeJS的服务。

GET /socket.io/1/?t=1417252232035 HTTP/1.1

Host: comet.zhihu.com

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://www.zhihu.com/

Origin: http://www.zhihu.com

Connection: keep-alive

返回:

HTTP/1.1 200 OK

Server: zhihu_nginx

Date: Sat, 29 Nov 2014 09:11:19 GMT

Content-Type: text/plain

Connection: keep-alive

Vary: Accept-Encoding

Access-Control-Allow-Origin: http://www.zhihu.com

Access-Control-Allow-Credentials: true

Content-Length: 36

rfmX2x_OC9aKyzZAGh3c:60:60:websocket

GET /oauth/auth/request_sina_token?next=%2Foauth%2Faccount_callback&state=78db9a8b58b2dab6970d4520907ad629&code=879c3a9aabdf5dfe69b92092204fe480 HTTP/1.1

Host: www.zhihu.com

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://www.zhihu.com/

Connection: keep-alive

授权成功返回如下参数:

  • code:表示授权码,必选项。通常授权码只能使用该码一次,并且会设置有效时间。
  • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

3、客户端使用授权码向认证服务器申请令牌。

这个过程发生在客户端后台,用户不可见,这也是授权码模式的特性,更安全。大致接口地址类似(服务端会验证client_id、client_secret、auth code的正确性或更新令牌 refresh_token):

http://localhost:8080/oauth2/access_token?client_id={AppKey}&client_secret={AppSecret}&grant_type=authorization_code&redirect_uri={YourSiteUrl}&code={code}

向认证服务器申请令牌包含以下参数:

  • grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
  • code:表示上一步获得的授权码,必选项。
  • redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
  • client_id:表示客户端ID,必选项
  • client_secret:表示客户端密钥,必选项。

4、如果授权码验证成功,则下生成一个令牌。

这个过程发生在服务端后台,服务端会验证client_id、client_secret、auth code的合法性,成功则生成一个令牌。

认证服务器返回,包含以下参数:

  • access_token:表示访问令牌,必选项。
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
  • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  • refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
  • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。

5、客户端使用访问令牌向资源服务器请求受保护资源。

客户端实现,请求用户保护的资源。

知乎成功后返回:

GET /oauth/account_callback?callbacktype=sina HTTP/1.1

Host: www.zhihu.com

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://www.zhihu.com/

Connection: keep-alive

6、资源服务器验证访问令牌的有效性则开放保护的资源。

服务端实现,验证令牌合法性后则开放用户授权的保护资源,很多时候,用户的资源是与权限对应的。令牌可能只包含了用户特定的授权凭据,准确的说,令牌对应用户授权时所赋予的一系列权限的集合。所以在这一步,除了校验令牌的合法性之外,服务端还需对该令牌是否拥有足够的权限执行被保护操作进行验证。

一些问题

简单例举我想到的一些问题吧

1.请求授权码过程服务端最好启用授权域(scope)需要对授权的令牌的有效权限进行验证,以免泄露过多用户数据 ,启用state,用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验。

2.获得授权码重定向的地址,为了防止有攻击者伪造重定向地址骗取用户授权,服务提供方应对授权时的重定向地址进行验证或判断是不是同一个域,所以申请应用的时候应该有appkey,appsecret,redirect_uri基础配置参数。

3.确保授权码一次性与有效时间,令牌有效时间验证,改用HTTPS来加密,确保通信内容不被第三方窃取。

Refer:

Docs » OAuth 2.0

http://oauthlib.readthedocs.org/en/latest/oauth2/oauth2.html

理解OAuth 2.0

http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

OAuth2授权原理

http://www.cnblogs.com/neutra/archive/2012/07/26/2609300.html

OAuth 2.0模式

http://www.dannysite.com/blog/?tag=204

OAuth 2.0安全案例回顾

http://drops.wooyun.org/papers/598

OAuth2.0 基础概述的更多相关文章

  1. Spring Security实现OAuth2.0授权服务 - 基础版

    一.OAuth2.0协议 1.OAuth2.0概述 OAuth2.0是一个关于授权的开放网络协议. 该协议在第三方应用与服务提供平台之间设置了一个授权层.第三方应用需要服务资源时,并不是直接使用用户帐 ...

  2. 创建自己的OAuth2.0服务端(一)

    如果对OAuth2.0有任何的疑问,请先熟悉OAuth2.0基础的文章:http://www.cnblogs.com/alunchen/p/6956016.html 1. 前言 本篇文章时对 客户端的 ...

  3. Spring Cloud Security OAuth2.0 认证授权系列(一) 基础概念

    世界上最快的捷径,就是脚踏实地,本文已收录[架构技术专栏]关注这个喜欢分享的地方. 前序 最近想搞下基于Spring Cloud的认证授权平台,总体想法是可以对服务间授权,想做一个基于Agent 的无 ...

  4. OAuth2.0概述

    OAuth2.0较1.0相比,整个授权验证流程更简单更安全,也是未来最主要的用户身份验证和授权方式. 关于OAuth2.0协议的授权流程可以参考下面的流程图,其中Client指第三方应用,Resour ...

  5. Laxcus大数据管理系统2.0(2)- 第一章 基础概述 1.1 基于现状的一些思考

    第一章 基础概述 1.1 基于现状的一些思考 在过去十几年里,随着互联网产业的普及和高速发展,各种格式的互联网数据也呈现爆炸性增长之势.与此同时,在数据应用的另一个重要领域:商业和科学计算,在各种新兴 ...

  6. OAuth2.0的理解&基础

    此文章是复制黏贴网上文章的,主要做自己备用着看(也加了自己的一点见解),喜欢的读者也可以看. OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2 ...

  7. asp.net core系列 57 IS4 使用混合流(OIDC+OAuth2.0)添加API访问

    一.概述 在上篇中,探讨了交互式用户身份验证,使用的是OIDC协议. 在之前篇中对API访问使用的是OAuth2.0协议.这篇把这两个部分放在一起,OpenID Connect和OAuth 2.0组合 ...

  8. SimpleSSO:使用Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端

    目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Security.SimpleSSO模拟OpenID认证 通过authorization co ...

  9. 【OAuth2.0】Spring Security OAuth2.0篇之初识

    不吐不快 因为项目需求开始接触OAuth2.0授权协议.断断续续接触了有两周左右的时间.不得不吐槽的,依然是自己的学习习惯问题,总是着急想了解一切,习惯性地钻牛角尖去理解小的细节,而不是从宏观上去掌握 ...

随机推荐

  1. Android杂谈--HTC等手机接收不到UDP广播报文的解决方案

    最近遇到个问题,在android手机上发送UDP报文的时候,HTC等机型(测试用HTC new one)接收不到广播报文,而其他的samsung, huawei, xiaomi, nexus等等均没有 ...

  2. 分享一个web应用程序池管理工具

    因为项目在联调阶段由于各种各样的原因需要重启应用程序池,而调试服务器基本都需要远登操作.同样的情况也会发生在线上,如果公司权限控制得比较严格,每次都要多部门的服务器权限申请的话有点麻烦, 所以抽点时间 ...

  3. HBase - Phoenix剖析

    1.概述 在<Hadoop-Drill深度剖析>一文当中,给大家介绍了Drill的相关内容,就实时查询来说,Drill基本能够满足要求,同时还可以做一个简单业务上的聚合,如果在使用Hive ...

  4. LoadRunner执行过程报错“Failed to connect to server "xxx.xxx.xxx.xxx:xx":[10060] connetion time out”

    执行性能测试过程中,LR报错: Action.c(6):Error -27796: Failed to connect to server "xxx.xxx.xxx.xxx:xx" ...

  5. phalcon开发工具(phalcon-devtools)

    一.简介 Phalcon提供的这个开发工具主要是用来辅助开发,比如生成一些程序的基本框架,生成控制器模型等.使用这个工具我们只需要一个简单的命令即可生成应用的基本框架. 二.下载 github: ht ...

  6. 【Web】Eclipse + Maven + Struts搭建服务器

    一.环境 系统:Windows7 IDE:Eclipse-Kepler Service Release 2 使用插件:Maven(请预先在电脑上安装Maven) 二.搭建 在Eclipse中新建一个M ...

  7. windbg加载sos.dll

    SOS.dll 中提供的 Son of Strike 扩展 (SOS),用于调试 WinDbg 中的托管代码.在启动了调试程序并将其附加到托管进程(或加载故障转储) .load C:\Windows\ ...

  8. java攻城师之路--复习java web之jsp入门_El表达式_JSTL标签库

    JSP 技术掌握:JSP语法 + EL + JSTL 为什么sun推出 JSP技术 ? Servlet 生成网页比较复杂,本身不支持HTML语法,html代码需要通过response输出流输出,JSP ...

  9. 详解SPI中的极性CPOL和相位CPHA

    SPI由于接口相对简单(只需要4根线),用途算是比较广泛,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间.即一个SPI的Master通过SPI与一个 ...

  10. Rpath handling on Linux

    The solution in the article below seems promising: http://www.blaenkdenum.com/notes/cmake/#rpath set ...