• 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):客户端重定向

  • 相关阅读:
    返回值与返回引用的问题
    C内存之指针传递
    Elasticsearch-Java中文搜索器(下)
    Elasticsearch-Java中文搜索器(中)
    Elasticsearch-Java中文搜索器(上)
    Redis和Memcache对比及选择
    Java + Tomcat + Memcached + Nginx 实现负载均衡~下
    Java + Tomcat + Memcached + Ecs 实现负载均衡~上
    Java -- 偏向锁、轻量级锁、自旋锁、重量级锁
    Java 锁与对象头
  • 原文地址:https://www.cnblogs.com/changrunwei/p/13149861.html
Copyright © 2020-2023  润新知