SSO —— 单点登录CAS与OAuth2
背景
在系统开发初期,系统很少,每个系统都有自己的登录模块,用户直接使用自己的账号进行登录即可。
但当功能不断完善,为了合理利用资源并降低耦合性,往往需要将单系统拆分为多个子系统。
以阿里系的网站为例,一个网站背后有众多的子系统,用户的一次交易或操作往往可能需要十多甚至几十个子系统的协作,如果每个子系统都需要用户进行登录验证,那么用户就需要登录几十次,这显然是不可行的。
那么现在我们面对的情况如下:
-
当前有多个子系统。
-
在任何一个子系统登录后,其他系统均无需再次登录。
-
如何存储证书。
-
如何验证证书。
一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,用户的一次登录能得到其他所有系统的信任,这就是单点登录。
使用cookie实现SSO
流程
讲解
将证书存储在客户端的cookie中,十分方便,但也带来两个问题
- cookie的安全性无法保证
对cookie进行加密。
- 跨域问题
强制将多个子系统域名设置成一致。(不太现实)
CAS
CAS官网上的标准流程,具体流程如下:
- 用户访问app系统,app系统是需要登录的,但用户现在没有登录。
- 跳转到CAS server,即SSO登录系统。 SSO系统也没有登录,弹出用户登录页。
- 用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器中写入SSO域下的Cookie。
- SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。
- app系统拿到ST后,从后台向SSO发送请求,验证ST是否有效。
- 验证通过后,app系统将登录状态写入session并设置app域下的Cookie。
至此,跨域单点登录就完成了。以后我们再访问app系统时,app就是登录的。接下来,我们再看看访问app2系统时的流程。
- 用户访问app2系统,app2系统没有登录,跳转到SSO。
- 由于SSO已经登录了,不需要重新登录认证。
- SSO生成ST,浏览器跳转到app2系统,并将ST作为参数传递给app2。
- app2拿到ST,后台访问SSO,验证ST是否有效。
- 验证成功后,app2将登录状态写入session,并在app2域下写入Cookie。
这样,app2系统不需要走登录流程,就已经是登录了。SSO,app和app2在不同的域,它们之间的session不共享也是没问题的。
OAuth2
(Open Authorization,开放授权)是为用户资源的授权定义了一个安全、开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息。
主要应用于第三方应用授权登录:在APP或者网页接入一些第三方应用时,时常会需要用户登录另一个合作平台,比如QQ,微博,微信的授权登录,第三方应用通过oauth2方式获取用户信息。
以微信登录为例:
- 用户访问第三方网站,第三方应用需要用户登录验证,用户选择微信授权登录
- 第三方应用发起微信登录授权请求
- 微信服务器拉起用户授权确认页面
- 用户授权通过
- 微信发送请求到第三方应用redirctUrl(第2步填写redirct_uri参数),返回凭证code与state(第2步自定义)
- 第三方应用获取到code之后,根据code获取accessToken
- 根据accessToken获取用户信息
- 对用户信息进行处理(用户是否第一次登录,保存用户信息,自定义token,session处理等)
- 返回结果(步骤1对应url或者重定向到首页)
CAS的单点登录和oauth2的最大区别