SSO
两者有很多相似之处,下面我们来解释一下这个过程。先来讲解 SSO,通过 SSO 对比 OAuth2.0,才比较好理解 OAuth2.0 的原理。SSO 的实现有很多框架,比如 CAS 框架,以下是 CAS 框架的官方流程图。特别注意: SSO 是一种思想,而 CAS 只是实现这种思想的一种框架而已
上面的流程大概为:
- 用户输入网址进入业务系统
Protected App
,系统发现用户未登录,将用户重定向到单点登录系统CAS Server
,并带上自身地址 service参数 - 用户浏览器重定向到单点登录系统,系统检查该用户是否登录,这是 SSO(这里是 CAS)系统的第一个接口,该接口如果用户未登录,则将用户重定向到登录界面,如果已登录,则设置全局 session,并重定向到业务系统
- 用户填写密码后提交登录,注意此时的登录界面是 SSO 系统提供的,只有 SSO 系统保存了用户的密码,
- SSO 系统验证密码是否正确,若正确则重定向到业务系统,并带上 SSO 系统的签发的 ticket
- 浏览器重定向到业务系统的登录接口,这个登录接口是不需要密码的,而是带上 SSO 的 ticket,业务系统拿着 ticket 请求 SSO 系统,获取用户信息。并设置局部 session,表示登录成功返回给浏览器
sessionId
(tomcat 中叫JSESSIONID
) - 之后所有的交互用
sessionId
与业务系统交互即可
最常见的例子是,我们打开淘宝 APP,首页就会有天猫、聚划算等服务的链接,当你点击以后就直接跳过去了,并没有让你再登录一次
用户登录/登录校验
登录时序图
按照上图,用户登录后 AuthToken 保存在 Cookie 中。 domain=test.com
浏览器会将 domain 设置成 .test.com,
这样访问所有 *.test.com 的 web 站点,都会将 AuthToken 携带到服务器端。
然后通过 SSO 服务,完成对用户状态的校验/用户登录信息的获取
登录信息获取/登录状态校验
用户登出
用户登出时要做的事情很简单:
- 服务端清除缓存(Redis)中的登录状态
- 客户端清除存储的 AuthToken
登出时序图
跨域登录、登出
前面提到过,核心思路是客户端存储 AuthToken,服务器端通过 Redis 存储登录信息。由于客户端是将 AuthToken 存储在 Cookie 中的。所以跨域要解决的问题,就是如何解决 Cookie 的跨域读写问题。
解决跨域的核心思路就是:
- 登录完成之后通过回调的方式,将 AuthToken 传递给主域名之外的站点,该站点自行将 AuthToken 保存在当前域下的 Cookie 中。
- 登出完成之后通过回调的方式,调用非主域名站点的登出页面,完成设置 Cookie 中的 AuthToken 过期的操作。
跨域登录(主域名已登录)
跨域登录(主域名未登录)
跨域登出
SSO 和 OAuth 的区别
首先熟悉一下 OAuth2.0 详解
SSO 是一种思想,或者说是一种解决方案,是抽象的,我们要做的就是按照它的这种思想去实现它
OAuth2 是用来允许用户授权第三方应用访问他在另一个服务器上的资源的一种协议,它不是用来做单点登录的,但我们可以利用它来实现单点登录。
在本例实现 SSO 的过程中,受保护的资源就是用户的信息(包括,用户的基本信息,以及用户所具有的权限),而我们想要访问这这一资源就需要用户登录并授权,SSO 服务器集成了 【登录+授权】 的功能(Authorization Server)负责令牌的发放等操作,这令牌即返回的 ticket,等价于 Access_Token 的。
整个过程中, SSO 内部集成了 OAuth 的前两步操作, 然后最后, 通过返回的 ticket ,发送回 SSO 服务器 (Resource Server),判断是否当前的 Token 是合法的。并返回用户信息。