SSO 之 CAS&OAuth 2.0


SSO 之 CAS&OAuth 2.0

SSO(Single Sign On)即单点登录,可以让用户只使用一份认证信息(如用户名、密码)来实现多个不同应用下同一用户的认证和授权

1. CAS(Central Authentication Service)

1.1 定义

CAS即中央认证服务,其是基于ticket的SSO的一种实现,通过提供一个统一的认证(登录)、授权服务,来协调用户在不同应用下的授权

1.1.1 组成

由cas server和cas client来组成

  • cas server

    负责请求的认证和授权

  • cas client

    负责发起认证和授权,一般为第三方应用

1.1.2 关键概念

  • TGT (Ticket Granting Ticket)

    代表client访问server后在server创建的一个session

  • CASTGC (CAS Ticket Granting Cookie)

    用于存放TGT,会被返回至client并存储

  • ST (Service Ticket)

    是一个由server生成的、一次性的票据,会被放入重定向的url中,用于后续的GET请求

1.2 流程

CAS Web flow diagram

流程如下

  • 用户首次访问站点A,没有此用户session信息,A将其重定向到cas server
  • server收到请求发现没有此用户的session信息(也即TGT),将其重定向到一个表单提交页面,提供id和pwd,以POST请求传送,其中url中需要放入service参数告知server要重定向的网址,此网址是站点A检验ticket的url
  • cas认证通过后,会创建<TGT,cas_session>,并创建一个ticket,之后创建重定向请求,请求的url就是service中指定的url,其中将TGT放入Set-Cookie,并在url放入ticket信息
  • 请求service指定的url,带上ticket
  • 站点A校验ticket,请求cas server进行校验,如果校验通过,则创建session,并返回sessionid
  • 用户携带包含站点A的sessionid的cookie访问站点A

从上可见,用户的认证信息只存储在cas server,用户想要登录站点A需要通过cas提供ticket来完成认证、授权,之后用户和站点A通过session来完成认证

2. OAuth 2.0

2.1 定义

OAuth是一种基于token的sso的一种实现,可以解决同一用户站点间的授权操作

2.1.1 组成

  • client

    客户端,发起认证、授权流程

  • Authorization Server

    认证服务器,用于处理认证请求

  • Resource Owner

    用户

  • Resource Server

    资源服务器,用于存放用户资源

2.1.2 关键概念

  • Access Token

    访问令牌

  • Authorization Grant

    授权方式

    • 授权码(authorization-code)
    • 隐藏式(implicit)
    • 密码式(password)
    • 客户端凭证(client credentials)

2.2 流程

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

RFC中给出的流程如上

2.3 实例

这里以返回授权码的方式来举例,例子来自GitHub OAuth 第三方登录示例教程 - 阮一峰的网络日志

假设想要访问draw.io这个网站,通过github授权的方式来获取用户在github仓库,获取其中的xxx.drawio文件

授权流程如下

  • draw.io让用户跳转到 GitHub。

  • GitHub 要求用户登录,然后询问"draw.io 网站要求获得 xx 权限,你是否同意?"

  • 用户同意,GitHub 就会重定向回 draw.io 网站,同时发回一个授权码。

  • draw.io 网站使用授权码,向 GitHub 请求令牌。

  • GitHub 返回令牌.

  • draw.io 网站使用令牌,向 GitHub 请求用户数据。

那么上面的流程中,每一步的详细流程如下

  • draw.io提供一个跳转到github授权页面的链接,url中需要指定response_type也就是授权类型,client_id也即draw.io在github注册时的id以及redirect_uri,用户跳转回draw.io的授权页面

    url形如

    https://github.com/oauth/authorize?
      response_type=code&
      client_id=CLIENT_ID&
      redirect_uri=CALLBACK_URL&
      scope=read
    
  • 用户点击链接后,先登录github账号,之后选择同意授权,接着跳转到redirect_uri,url中会拼接AUTHORIZATION_CODE授权码

    url形如

    https://draw.io/callback?code=AUTHORIZATION_CODE
    
  • draw.io取出AUTHORIZATION_CODE,向github再起发起请求,url需要拼接client_id,client_secret即draw.io在github认证方注册时得到的密钥,用于github验证client是否在此报备过,grant_type即授权方式,code即授权码,以及redirect_uri定向到draw.io的某个路径

    url形如

    https://draw.io/oauth/token?
     client_id=CLIENT_ID&
     client_secret=CLIENT_SECRET&
     grant_type=authorization_code&
     code=AUTHORIZATION_CODE&
     redirect_uri=CALLBACK_URL
    
  • github收到请求后,生成token并重定向到redirect_uri

    请求体形如

    {    
      "access_token":"ACCESS_TOKEN",
      "token_type":"bearer",
      "expires_in":2592000,
      "refresh_token":"REFRESH_TOKEN",
      "scope":"read",
      "uid":100101,
      "info":{...}
    }
    
  • draw.io收到token后取出token,后续请求就可以使用token来完成授权

3. 比较

3.1 区别

  • cas

    全局只有一个认证、授权中心,所有的其他关联的站点都需要借助ticket通过cas来完成认证,关联站点与用户间使用session来认证

  • oauth

    所有持有用户资源的站点都可以向想要获取资源的第三方应用提供授权服务,使用资源站点提供的token来完成授权

3.2 特性

  • cas

    适用于集团使用,如同一公司的多个站点,认证均通过cas完成,除cas外的站点,只有在cas认证过的前提下,才可以和用户间保留一个具有时效性的认证信息

  • oauth

    适用于资源站点向意欲获取资源站点间的授权,如用户登录spotify,可以使用google、facebook等已经认证过的用户信息来跳过认证,进行授权操作,如spotify想要获取查看用户的好友列表、基本信息等权限

3.3 token与ticket

ticket有如下特性

  • 一次性

    只可以被消费一次

  • 介入性

    用户只负责在站点和cas间传递ticket,ticket的合法性只作用在cas和站点间

token有如下特性

  • 时效性

    token可以设定过期时间

  • 可控性

    token可以只对特定资源有效

  • 保密性

    相较于每个站点都存留用户名密码,使用token更加轻量、安全

  • 便捷性

    对于类似于draw.io这类站点,其只需要获取存留XXX.drawio文件的资源站点的授权,如github,无需在draw.io创建用户信息,提供用户名、密码,直接使用资源站点的用户信息即可

# 参考

Single sign-on - Wikipedia

CAS - CAS Protocol (apereo.github.io)

OAuth 2.0 的一个简单解释 - 阮一峰的网络日志 (ruanyifeng.com)

理解OAuth 2.0 - 阮一峰的网络日志 (ruanyifeng.com)

rfc6749 (ietf.org)