首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单点登录方案[学习]

单点登录方案[学习]

作者头像
wangxl
发布2018-03-07 11:26:58
1.6K0
发布2018-03-07 11:26:58
举报
文章被收录于专栏:PHP在线PHP在线

引子

昨天在网上看到一个帖子,帖子的内容大概是说领导要求一个苦B程序员实现一个单点登录的系统,将各个业务系统联系起来,但不能修改其他业务系统的源码。

其实,在企业信息化过程中,通常有多个应用系统,每个应用系统中,有独立用户管理模块,用来保存每个用户对应的账号,权限等信息,为了减少每个人登录系统时,记忆密码的麻烦,经常会用到单点登录功能。

我们公司用的就是CAS单点登录系统,我们抛开CAS这种成熟的单点登录系统,从头开始思考和设计一下单点登录如何实现。

需求简述

单点登录系统保存了用户的登录名和密码,上网用户在单点登录系统中认证成功后,就可以直接登录各个业务系统。

这个需求看似简单,但实际暗藏玄机:

1. 用户访问任何一个业务系统时,如果已经在单点登录服务器中认证成功,那么可以获取对应的权限,访问对应的界面。

2. 用户如果在其中任何一个业务系统中点击“注销”按钮后,那么不能继续访问其他业务系统,如果访问,必须重新登录

3. 用户访问任何一个业务系统时,如果尚未在单点登录服务器中认证成功,那么需要跳转到单点登录界面,输入用户名密码,校验成功后,再回到原来的访问界面

4. 用户关闭浏览器后,再次打开,不能继续访问其他业务系统

实现方案

根据上述需求,我们可以考虑出很多套实现方案,这些方案各有优缺点,根据各个方案的比较,选出实现最简单、功能最完善、性能最优化的方案,作为最终的实现方案。

我们知道用户点击业务系统中的各个连接,访问业务系统时,可能存在以下场景

场景1:用户尚未在单点登录系统中完成登录,此时单点登录系统没有当前用户的在线信息

场景2:用户已经在单点登录系统中完成登录,但尚未在当前业务系统中完成登录,当前业务系统中没有此用户的在线信息

场景3:用户已经在单点登录系统中完成登录,并且也在当前业务系统中完成登录

场景4:用户已经在单点登录系统中注销,但在当前业务系统中尚未注销

对于场景1,此时业务系统应该拦截用户的访问请求,并且将用户重定向到单点登录系统中,当用户在单点登录系统中完成登录后,再在当前业务系统中执行用户登录的操作,再重定向到用户上次访问的界面,让用户能够正常访问业务系统

对于场景2,此时业务系统应该拦截用户的访问请求,并且与单点登录系统通信,获取当前用户的在线状态后,在当前业务系统中执行登录操作,再向用户返回上次请求的结果界面,让用户能够正确访问业务系统

对于场景3,此时业务系统应该拦截用户的访问请求,并且与单点登录系统通信,校验用户是否在线,再向用户返回上次请求的结果界面,让用户能够正确访问业务系统

对于场景4,此时业务系统应该拦截用户的访问请求,并且与单点登录系统通信,校验用户是否在线,因为此时用户已下线,所以在当前业务系统中完成注销操作,并且将用户跳转到单点登录的登录界面,后续处理与情况1一致。

方案一

  • 方案描述

1. 用户访问业务系统时,业务系统可以根据HTTP请求的源IP,去单点登录系统中查询

1). 如果此IP对应的用户尚未认证,跳转到单点登录系统的登录界面,要求输入用户名和密码进行认证

2). 如果此IP对应的用户已经认证,业务系统认为此用户登录成功,允许其继续访问业务系统

2. 在单点登录系统的登录界面或后台session中,需要保存用户上次访问的URL,以便于用户认证成功后,能够再次回到上次访问的界面

3. 用户在单点登录系统的登录界面输入用户名密码登录成功后,单点登录系统记录此用户的身份以及对应的IP地址,再将浏览器重定向到上次访问的URL中,这样就回到了步骤1,此时用户已经认证成功,可以访问业务系统。

4. 用户在任意业务系统中单击注销按钮时,业务系统完成系统自身的注销操作后,将界面重定向到单点登录系统的注销URL中,并自动在单点登录系统中注销用户信息

  • 优点

1. 只要浏览器支持基本的重定向功能,就可以按照本方案实现

  • 缺点

1. 要实现上述需求,需要修改业务系统的代码,对于.net和java编写的业务系统,需要两套不同的代码

  • 安全性

1. 根据用户的IP地址进行用户身份的判定,会带来以下安全问题:

1). 如果用户IP修改后,需要重新认证才能继续访问业务系统

2). 如果用户恶意仿冒领导的IP地址,那么可以越权访问自己没有权限的业务系统

3). 在公共的PC中,前一个用户关闭浏览器,没有点击注销按钮,那么后续使用这台PC的所有人,都可以直接使用前一个人的账号访问业务系统

  • 性能

每次访问业务系统的任何一个URL,都需要与单点登录系统联动,如果用户量很大,单点登录系统会成为瓶颈

方案二

  • 方案描述

1. 用户使用单点登录系统的登录界面,输入用户名和密码登录成功后,单点登录系统为用户浏览器安装一个cookie,cookie的值是一个全局唯一的字符串 (下文称为ticket),理论上这个唯一值永远不能重复,用来标识用户的一次成功的登录请求。同一个用户,在同一个时刻登录两次,得到的ticket值 应该完全不同。

2. 用户访问业务系统时,如果当前用户尚未在业务系统中登录,就将界面重定向到单点登录系统中,这时访问的URL前缀是单点登录系统的前缀

1).如果用户已经在单点登录系统中完成登录,那么此时用户访问单点登录URL时,就会带上步骤1中的ticket,单点登 录系统识别出此ticket,知道当前用户已经认证过,将用户界面再次跳转到业务系统中,并且携带上述ticket,业务系统也将此ticket安装到 cookie中,后续对于此业务系统的所有访问,都直接根据ticket去单点登录系统中查询用户是否在线就可以了

2).如果用户尚未在单点登录系统中完成登录,那么此时用户访问单点登录URL时,无法携带上步骤1中的ticket,单点 登录系统为展示登录界面,用户输入用户名和密码登录成功后,将用户界面再次跳转到业务系统中,并且携带上述ticket,业务系统也将此ticket安装 到cookie中,后续对于此业务系统的所有访问,都直接根据ticket去单点登录系统中查询用户是否在线就可以了

3. 用户访问业务系统时,如果当前用户已经在业务系统中登录,那么访问业务系统的cookie中,会携带单点登录ticket,业务系统根据此ticket,去单点登录系统中查询用户是否已经在线,如果已经在线,就允许继续访问,否则就执行注销操作

4. 用户在任意一个业务系统中执行注销操作时,业务系统在拦截注销操作,并且与单点登录系统联动,在单点登录系统中完成注销后,再跳转回业务系统的注销界面

  • 优点

1. 单点登录系统的整套拦截和转发流程,可以封装成为公共组件,只需少许修改业务系统代码

2. 所有业务系统都可以使用上述方案增加与单点登录系统的联动功能

  • 缺点

上述单点登录功能,依赖浏览器的cookie功能,如果浏览器不支持cookie,将无法使用

  • 安全性

1. 用户恶意仿冒他人IP,也无法获取对应业务系统的访问权限,安全性比方案一高

2. 恶意用户拦截HTTP请求,获取cookie中进行仿冒,同样可以获取他人对于业务系统的访问权限

  • 性能

当业务系统很多、上网用户很多时,每次访问业务系统的任何一个链接,都需要与单点登录系统联动,查询用户是否在线,单点登录系统可能成为瓶颈

方案比较

上述方案,都需要对于现有系统进行一些修改,但方案二的安全性相对较高

方案二中提到的安全性问题,可以通过定期更新ticket值,或每次访问都生成不同的ticket值来进行规避。

上述方案,因为涉及对于单点登录系统的大量访问,所以会使得单点登录系统成为瓶颈,可以采用如下方案在安全性不降低很多的情况下规避性能问题:

方案一:业务系统记录上次与单点登录系统联动,获取用户状态的时间,并且n分钟内,所有用户对于业务系统的情况,都不和单点登录系统联动

方案二:业务系统和单点登录系统之间采用性能更高的网络协议,例如UDP协议进行在线状态的交互,按照现有经验,因为UDP报文头部较小,报文有效内容比例大,同时报文长度短,比现有的HTTP协议性能可以提高1~2个数量级,每秒支撑1000次查询请求,是没有问题的。

总结

上述方案二,是借鉴CAS单点登录系统的实现进行描述的。

对于第一章节提到的那种对于现有业务系统不进行任何修改的方案,个人认为没有太好的实现方法,可能可以通过简单修改业务系统的asp,php或jsp代码实现,但是一点不修改,目前没有太好的方案可以做到。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2014-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 php 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档