互联网OAuth 2.0开放授权原理

  OAuth 2.0是一个开放授权协议,是1.0的更新替代版,据说是比1.0简化方便了许多。这个协议是用于授权访问开放资源的,但我觉得对自己最大的方便的是很多网站支持的话,可以方便地用授权账号登陆,而免除注册-激活-登陆这些繁琐的步骤。
OAuth 2.0 图标

1. OAuth 2.0 协议介绍

1.1 OAuth 2.0 授权过程概述

  下面,以客户端Web应用程序请求资源的例子(最常见的Authorization Code认证类型),描述一下OAuth 2.0 授权请求的过程,想必使用过的人(作为Resource Owner)一定很熟悉吧。
  当用户访问这个客户端Web应用程序的时候,会提示选用通过Facebook/Google/Twitter方式登陆;用户点击对应的登陆按钮,然后用户会被导向对应登陆界面,完成登陆后提示是否允许客户端Web应用程序访问自己的某些数据,用户选择允许;接着认证程序将用户导向到redirect URI并附加一个授权码(authentication code),redirect URI是客户端Web应用注册时候提供的地址,注册时候认证程序会给注册的客户端Web应用client id和client password;用户访问redirect URI,在底层客户端Web应用会将client id,client password和授权码回传给服务器,成功后认证程序返回access token。
  自此,当客户端程序得到了access token,就可以用这个令牌访问申请的资源信息了。

1.2 OAuth 2.0 角色类型、客户类型和客户属性

  OAuth 2.0 共有四种角色,分别是:Resource Owner、Client Application、Resource Server、Authorization Server。Resource Owner一般指的拥有资源的用户或者程序,Client Application是请求资源的程序,认证服务器和Resource Server可以是同一台服务器或者不同的服务器构成的。
  协议中,OAuth 2.0有两种客户类型:Confidential和Public,前者是能够保存认证服务器给予的client password,用以让服务器识别客户,常用于Web App;后者用于不能保存client password的情况,比如手机App或者桌面App,以及Javascript应用程序。
  客户属性(Profiles)包括Web Application、User Agent和Native:Web Application通常包括Browser端和Server端,用户密码常常被保存在Server端,因此可以是Confidential的类型;User Agent常常是运行在浏览器中的Javascript小程序或者小游戏;Native通常是运行在移动端或者桌面的应用程序。

1.3 OAuth 2.0 认证

整个认证过程包括:

1.3.1 客户端应用向认证服务器注册

  首先,开发的应用程序需要向Facebook/Google/Twitter这类Resource Server的认证服务器进行注册,然后认证服务器会为客户端应用提供唯一的client id和client password,同时客户端程序还需要向认证服务器提供redirect URI,一旦客户端通过了认证服务器的认证,返回客户端之后Resource Owner将被带到这个redirect URI。

1.3.2 认证授权(Grant)

  主要是客户端程序通过认证服务器的认证之后,Resource Server授权批准给客户端程序的权限。其认证和授权包括四种类型,每一种都包括不同的安全属性:Authorization Code、Implicit、Resource Owner Password Credentials、Client Credentials。

1.3.2.1 Authorization Code

  如上面概述的过程,是最常见也是最严格的认证模式:

(1)用户访问应用程序;
(2)应用程序提示用户通过Facebook/Google/Twitter方式登陆;
(3)用户被重定向到了认证服务器,同时应用程序附加自己的client id给认证服务器;
(4)用户在认证服务器上登陆,登陆成功之后提示用户是否Grant应用程序访问资源,用户允许后被重定向到应用程序;
(5)当回到应用程序后,认证服务器将用户导向到redirect URI,同时附加authorization code;
(6)当redirect URI被访问后,应用程序和认证服务器就直接相连了,应用程序向认证服务器发送authorization code、client id、client password;
(7)认证服务器接受这些信息后,返回access token;
(8)应用程序之后通过access token访问资源信息;

Authorization Code认证过程

1.3.2.2 Implicit

  相比 Authorization Code认证方式简化了过程,当用户登录认证服务器完成认证,然后定向到redirect URI,此时认证服务器直接返回access token,而不是上面的authorization code。
  这种情况一般是User Agent和Native的类型,Web Server不会保存client password/access token,当然User Agent或者Native App保存client password/access token在本地也是不安全的。
Implicit认证过程

1.3.2.3 Resource Owner Password Credentials

  通过交付用户账户和密码给应用程序,授权应用程序访问用户资源。这种情况必须极度信任该应用程序才行,想想你交付的可是账户和密码哦!

1.3.2.4 Client Credentials

  授权应用程序访问公共资源,而不特定针对某个特别的用户情况的。

1.4 OAuth 2.0 请求和响应格式

  针对上面的四种认证授权类型,分别有不同的请求和响应数据格式

1.4.1 Authorization Code

  包括两个请求和两个响应

  • 认证请求
    response_type: code
    client_id: 认证服务器提供的client_id
    redirect_uri: 应用程序注册的redirect URI
    scope: 申请的权限、范围
  • 认证响应
    code: 认证服务器返回的authorization_code
  • 认证错误
    error: 预先约定的错误码
    error_description:
    error_uri: 指向错误详细描述的页面
  • Token请求
    client_id:
    client_secret:
    grant_type: authorization_code
    code:返回认证服务器给的authorization_code
    redirect_uri:
  • Token响应
    access_token:
    token_type:
    expires_in: access_token失效的时间,用秒计量
    refresh_token:

1.4.2 Implicit

  包括一个请求和一个响应

  • 请求
    response_type: code
    client_id: xxx
    redirect_uri:
    scope:
  • 响应
    access_token:
    token_type:
    expires_in:
    scope:
  • 错误
    同上。

1.4.3 Resource Owner Password Credentials

  包括一个请求和一个响应

  • 请求
    response_type: password
    username:
    password:
    scope:
  • 响应
    access_token:
    token_type:
    expires_in:
    refresh_token:

1.4.4 Client Credentials

  包括一个请求和一个响应

  • 请求
    grant_type: client_credentials
    scope:
  • 响应
    access_token:
    token_type:
    expires_in:

2. OAuth 2.0 协议举例

  本着实践的精神,试了一下国内第一大浪的开放平台的OAuth授权。

2.1 注册账户,创建应用

  在新浪微博开放平台注册开发者账户,然后创建一个应用,得到应用的信息如下:

应用名称:测试应用的哈
App Key(Client ID):476302957
App Secret(Client Password):1dd5950b4c7165a4203ae9a5b986c105
创建时间:2016-05-23
回调页面:http://abc.com/

2.1 采用新浪提供的授权接口,进行Authorization Code授权请求

  新浪Authorization Code授权请求的URL格式如下(GET方式):
https://api.weibo.com/oauth2/authorize?client_id=476302957&response_type=code&redirect_uri=http://abc.com/
授权确认界面

2.2 获取授权码,换取access_token

  上面一部授权允许后,会转到redirect URI,并附加授权码
获取授权码

  然后按照换取access_token的地址,换取access_token。这里需要注意的是,请求方式必须是POST的,否则会返回不支持的请求类型的错误。

1
https://api.weibo.com/oauth2/access_token?client_id=476302957&client_secret=1dd5950b4c7165a4203ae9a5b986c105&grant_type=authorization_code&redirect_uri=http://abc.com/&code=c7502d6f5d015f7ae99b44a9c9d57cd3

换取access_token

2.3 使用access_token

  得到了access_token,就可以当作令牌访问用户的授权数据了,比如下面将会得到用户好友的列表:

1
https://api.weibo.com/2/friendships/friends.json?screen_name=nicol_tao&access_token=2.00rfgxpB0lJWOW042307510b4MBhGC

access_token返回用户好友列表

本文完!

参考