关于sso单点登录系统的一些想法

系统方案基于httpservice,在此不探讨用户注册、停用等问题,只探讨登录问题。
必要条件:客户端需要维护自己的session队列,系统基于session实现单点登录

客户端、服务器端均需要提供几个连接 session注销、session登录、session校验等几个url

用户登录,当用户请求需要权限页面时,首先请求"session校验"判断用户是否已经在服务器登录了,如果已经登录服务器返回登录用户名信息,完成登录,否则跳转到服务器"session登录"完成用户登录,并跳转回原页面。
当用户在客户端点击注销按钮通知服务器用户注销,服务器发送到所有客户端"session注销"通知此用户下线。
服务器需要维护各个客户端sessionid与服务器sessionid的对应关系,注销时直接通过sessionid通知客户端做相应操作即可。

sso服务器主要工作需要维护各个客户端的sessioid对应关系、并定时轮询客户端"session校验",维护session,保证用户不失效。

sso服务器如果重启后,原有客户端的session注销会存在异常,但是这种异常通常是短时间的, 当客户端session失效异常即可消除,目前没有想到好的方法解决这个问题。
重启后,sso服务器应该立即对所有客户端的session进行轮询,将服务器数据队列完成创建,以便用户登录sso时完成对了同步。
要解决的话就必须保证浏览器客户端访问一次sso服务器,当完成一次访问后即可完成对列的维护。

此方案可以解决基于cookie的sso问题

缺点,不能实现匿名登录,不过应该可以变相实现,问题不大。
另外,必须保证sso服务器高可用,一旦当机可能会造成系统大面积无法登陆系统,导致系统瘫痪。


[color=red][b]浅谈基于WEB和WAP的SSO登录[/b][align=left][/align][/color][size=large][/size]
一、初步方案
最近公司要开发新版系统,有幸和几个组员第一时间进入新版的用户中心的开发,按照公司的要求,新版的用户中心要实现单点登录,建议不使用SESSION,以减轻服务端维护SESSION的成本。于是考虑使用cookie+cache来维护会话,实现单点登录。
但是由于系统存在WAP客户端,不能使用COOKIE,使用COOKIE+cache的方案似乎无法得到解决,而WAP客户端中又存在两个应用,简版和3G彩版,进一步讨论之后,决定WAP之间与WEB之间不同步登陆状态。但是WAP端各应用要进行登录状态同步。
于是出来一个初步的方案,在WEB客户端端使用cookie+cache,在WAP客户端端依然使用session+cache实现单点登录,无论是WEB客户端或者WAP客户端,都调用后台发布的服务,本身并不直接连接数据库,后台服务组集群管理集中式的缓存,各个客户端维护自身的缓存。
1、缓存组件的选择
由于存在WEB端与WAP端,应用都在集群环境中,所以使用一个好的分布式缓存似乎也是项目稳定性的关键,Terracotta+ehcache是个不错的选择,由于hibernate官方推荐的第三方缓存组件是ehcache,如果服务端已经使用了ehcache作为hibernate缓存组件,再对系统进行分布式缓存集成Trracotta,那就显得非常的简单。但我们是开发新的项目,而使用集中式缓存管理策略对分布式缓存的效率和缓存服务器扩展有一定的好处,于是决定采用memcache进行缓存服务器的搭建。
2、会话维护与过期所存在的问题
使用SESSION登录会比较简单,server端可以设置session的过期时间。
而使用COOKIE设置过期时间,浏览器会将COOKIE数据写入硬盘上保存,这时即使用户关闭浏览器,COOKIE文件还未到过期时间还是保存在硬盘上,这就存在一些不安全的隐患,但是如果设置COOKIE的过期时间为一个小于0的数值,则COOKIE保存在客户端的内存中,这样,用户只要不关闭浏览器,COOKIE就不会失效,也会存在一些安全隐患。
用户会话的cache信息也将会有问题,由于cache在创建的时候就会有一个创建时间,创建之后,根据配置的缓存策略来管理缓存元素。cache一旦创建,只要到了配置的过期时间,就一定会销毁缓存元素,这样,客户端的会话即使依然真实存在,也无法通过cache来获取用户的数据,用户的登录状态也将消失。
3,会话维护与过期存在问题的解决方案
使用COOKIE进行会话的维护,为了使得COOKIE的信息尽量的保密和安全,需要对COOKIE进行加密,而由于COOKIE的会话的设计依然存在一些问题,所以使用另外一种方案对COOKIE进行设计,用户登录时,生成一个名为SSO_LOGIN的cookie,此COOKIE保存三个信息,用户名|生成时间|加密数据。用户登录时,将用户名+生成时间+密钥进行MD5加密,然后将用户名,生成时间和MD5的加密数据连起来作为cookie的VALUE值写入客户端,并将COOKIE的过期值设置为负数(关闭浏览器失效),通过后台发布的服务将用户信息写入中心缓存中,这样,用户每进行一次请求,都直接从中心缓存中获取用户信息。当用户客户端的COOKIE失效时,让用户进入登陆流程;当中心缓存中无用户信息时,也让用户进入登陆流程。这样就必须保证用户在活动期间,中心缓存中的用户信息不能过期,有两种解决方案,一是设置缓存策略时间较长,如果用户数比较多,无疑会较大程度的提高服务器管理缓存所花的成本。第二种方案,用户每获取一次信息,则更新一次缓存,将用户信息的缓存策略的过期时间设置和COOKIE的过期时间一致。虽然也在一定程度上提高了缓存管理的成本,但是笔者认为第二种比第一种要好一些。
4,总结
通过以上的分析,可以总结出来整个单点登录的过程:WEB客户端,用户登录时,生成COOKIE和中心缓存,用户每进行一次请求,首先取出COOKIE,验证加密数据;其次取出COOKIE的生成时间与现在的时间进行对比,验证是否过期;再次,若验证通过则调用服务获取缓存中的用户信息并刷新缓存的生成时间,若验证不通过或者过期,则进入用户登录流程;最后,获取到用户信息之后,刷新COOKIE的生成时间,重新写入COOKIE到客户端。这样只要用户的浏览器中存在相关的COOKIE并没有过期(用户关闭浏览器或者在超过设置COOKIE的有效期),则在该域名的路径下面所有的项目都可以获取到用户登录状态和信息。
而WAP端的SSO登录将变得更为简单,用户登录之后,获取服务器分配给用户浏览器的SESSIONID,将SESSIONID作为KEY值,用户信息作为VALUE值生成中心缓存,这样用户访问该域名下的所有的应用,只要使用的是同一个浏览器(SESSIONID无变化)
,并且在SESSION的有效期内,都可以获取用户信息,同步登录信息,实现单点登录


[align=left]sso一般有两种实现,基于agent和proxy。 [/align][size=large][/size][b][/b]

CAS是基于agent的。一次完整的sso过程为

1.用户第一次打开系统A的页面
2.系统A发现当前用户没有登录
3.系统将登录过程委托给本地的agent,比如CAS的java client或者web client
4.本地agent将页面转向给sso系统,并且生成一个随机的token
5.用户在sso系统上输入账号密码,登录成功
6.sso系统调用系统A上agent的一个url,将账号信息加密发送回A
7.该agent通过生成的token解密账号信息,传送到系统A内部。
8.系统A接收到该账号随后进行授权操作。

如果用户打开系统B页面,而该系统也运行同一个SSO的agent,那么过程同上面类似,只是跳过第5步。这时用户浏览器都是处于SSO系统所在域,所以可以直接将以前用户的账号信息发回。


基于proxy的实现方案我只看到过novel iChain实现。这种方案需要通过DNS将多个系统的域名配置在一个承担SSO的Proxy上。当用户输入系统地址打开页面时,会首先链接到这个Proxy,再由Proxy转发到实际系统。原有系统因为用户没有登录,那么会返回登录页面,这时候iChain会截获这个登录页面,用自己的登录页面代替。用户在iChain提供的页面中输入用户名和密码,随后iChain根据LDAP(Novel的LDAP可以说是这行的老大了)中的信息查询出原有系统的用户名和密码,通过一次Http Post将用户账号发送给原有系统。

如果用户打开新系统页面,那么基本不骤不变,只是iChain返回自己登录页面时,因为在同一个域中,可以发现该用户已经登录过,然后就直接Http Post到新系统而不出现登录页面。

iChain的登录过程是从我参加的一个项目推测的,没有官方的技术文档,有哪位朋友熟悉请修正一下。

其实SSO只是最简单的一个步骤,如何做好多系统之间的账号同步和授权才是大难题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值