OAuth2

OAuth2

OAuth2是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,如qq登陆、微信登陆、微博登陆。


OAuth的产生
需求:有一个“云打印”网站,可以将用户存储在google的照片打印出来。用户为了使用该服务,必须让“云打印”读取自己存储在google上的照片。但google只有得到用户授权才会同意“云打印”读取这些照片。
方案1:用户把用户名密码告诉“云打印”,然后“云打印”去google获取照片并打印。
问题:1、用户的google用户名密码泄露。2、“云打印”拥有了该用户在google网盘上所有的权限,即“云打印”可以访问该用户存储在google网盘上的所有文件。3、google只能使用用户名密码认证,不能使用第三方验证,比如手机验证、邮箱验证。
OAuth2方案:使用OAuth2,”云打印”在获取用户的授权后可以从google获取一个绑定用户的token,”云打印”可以使用这个token去访问用户允许它访问的数据,且token有默认的有效时间,用户也可以手动取消token的有效性。


OAuth2名词
1、Third-party application:即”云打印”
2、Http service:即google
3、Resource Owner:用户
4、User Agent:浏览器
5、Authorization Server:认证服务器,即谷歌专门用来提供认证服务的服务器。
6、Resource Server:资源服务器,即谷歌网盘服务器。


会话机制常用的有两种
session方式:用户发送用户名密码,服务器校验并生成session并发送session id给客户端,客户端保存在cookie中,下次访问携带cookie。
token方式:区别,服务器不生成sesseion id,生成token发送给客户端,客户端可以把token放在cookie中,也可以不放在cookie中,下次访问携带token。

OAuth2使用token方式


OAuth2协议大致流程

     +--------+                               +---------------+
     |        |--(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 ---|               |
     +--------+                               +---------------+
1、第三方应用(Client)向用户请求授权。
2、用户同意授权。(Grant,同意)
3、第三方应用带着用户的授权向认证服务器请求令牌。(Token,令牌)
4、认证服务器返回令牌。
5、第三方应用带着令牌向资源服务器请求资源。
6、资源服务器返回资源。

 Authorization Grant——用户授权有四种模式
1、授权码模式
2、简化模式(隐式模式)
3、密码模式
4、客户端模式


授权码模式

     +----------+
     | 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) 

Resource Owner——个人用户  Client——第三方应用后台服务器  User Agent——用户代理,即浏览器  Authorization Server——认证服务器

CSDN使用qq授权登陆:
1、在csdn.net注册页面点击qq小图标,浏览器访问:https://passport.csdn.net/v1/register/authorization?authType=qq
  这是csdn.net的一个地址,authType=qq表示使用qq授权登陆;另外csdn.net还支持github、微博、百度、脉脉的授权登陆
2、Client从认证服务器获取授权码

  Client自动调用腾讯对外开放的接口https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=100270989&response_type=code&redirect_uri=https://passport.csdn.net/account/login?pcAuthType=qq&state=test

    官网示例,使用x-www-form-urlencoded格式组织参数
    GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: server.example.com

  Client携带的参数:response_type=code,表示使用授权码模式;client_id,表示客户端标识,即上图中的Client Identifier,此字符串唯一代表此客户端,此字符串不保密,此字符串要暴露给个人用户;redirect_uri表示重定向url,即上图中的Redirection URI;state为了防止csrf攻击。
  用户输入的参数:qq用户名、qq密码,即上图中的 User authenticates
3、认证服务器返回授权码

  Authorization Server使浏览器重定向到Client指定的接口,并把Authorization Code添加到redirect_uri后面。Authorization Code在发布不久后必须过期,以降低泄露风险;最大的过期时间推荐为10分钟。Authorization Code只能使用一次;如果再次使用,认证服务器必须拒绝请求,如果可以的话,还应该废除此前基于此Authorization Code发布的token。

官网重定向示例,使用x-www-form-urlencoded格式组织参数
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

4、Client向认证服务器获取令牌

Client后台服务器使用HTTPS携带Authorization Code访问Authorization Server。

     官网示例:
     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
   //grant_type的值必须是authorization_code,code是上一步认证服务器返回的,redirect_uri必须和获取授权码时的地址相同

5、认证服务器返回令牌

Authorization Server返回Access Token、Refresh Token到Client后台服务器,并使用后台服务器重定向到资源服务器

     官网示例:   
     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }
 

简化模式(隐式模式)

简化模式不支持刷新token的发放;第三方没有服务器;第三方通常通过浏览器里的javascrpt和服务提供方交互。

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          ^
          |
         (B)
     +----|-----+          Client Identifier     +---------------+
     |         -+----(A)-- & Redirection URI --->|               |
     |  User-   |                                | Authorization |
     |  Agent  -|----(B)-- User authenticates -->|     Server    |
     |          |                                |               |
     |          |<---(C)--- Redirection URI ----<|               |
     |          |          with Access Token     +---------------+
     |          |            in Fragment
     |          |                                +---------------+
     |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
     |          |          without Fragment      |     Client    |
     |          |                                |    Resource   |
     |     (F)  |<---(E)------- Script ---------<|               |
     |          |                                +---------------+
     +-|--------+
       |    |
      (A)  (G) Access Token
       |    |
       ^    v
     +---------+
     |         |
     |  Client |
     |         |
     +---------+

1、Client发送请求以获取token,对应(A)(B),请求示范:

    // 使用https发送以下请求:
    GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: server.example.com 

2、认证服务器返回token,响应示范:

     // "application/x-www-form-urlencoded" format
     HTTP/1.1 302 Found
     Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600

返回的token在url的部分。
url格式:
[scheme:][//host:port][/path][?query][#fragment]
http://www.baidu.com:80/find?name=xxx&sex=nam#state=xxx
url的fragment以#号开头


密码模式

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          v
          |    Resource Owner
         (A) Password Credentials
          |
          v
     +---------+                                  +---------------+
     |         |>--(B)---- Resource Owner ------->|               |
     |         |         Password Credentials     | Authorization |
     | Client  |                                  |     Server    |
     |         |<--(C)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+

此模式第三方会获得到用主的用户名密码,适用于用户非常信任第三方的情况下。

1、请求令牌

     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=password&username=johndoe&password=A3ddj3w

2、返回令牌

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }

客户端模式 

     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(A)- Client Authentication --->| Authorization |
     | Client  |                                  |     Server    |
     |         |<--(B)---- Access Token ---------<|               |
     |         |                                  |               |
     +---------+                                  +---------------+

1、请求令牌

     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
     Content-Type: application/x-www-form-urlencoded

     grant_type=client_credentials

2、返回令牌

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "example_parameter":"example_value"
     } 


Client_id

授权服务器向注册的客户端颁发客户端标识符——唯一字符串。


协议端点(Protocol Endpoints)

两个授权服务器端点:授权端点、令牌端点
一个客户端端点:重定向端点

授权端点(Authorization endpoint):只适用于授权码模式和简化模式
令牌端点(Token Endpoint):第三方提交刷新token或用户授权到认证服务器此端点,以获取token
重定向端点(Redirection Endpoint):客户端重定向

 

posted @ 2020-06-16 23:20  zhuangrunwei  阅读(355)  评论(0编辑  收藏  举报