在不同域中各个系统拥有自已独立的用户系统时的单点登录问题
我们在实现业务中经常会碰到多个系统各自有各自的用户登录系统,而且这些系统是各自运行在各自的域下,所以要实现这些系统用户的单点登录就是个问题了,所以自己想了一个方案希望看看是否可行。
1.sso站点必须是单独一个站点。
我把sso单独设立一下站点,这个站点可以单独一个域名,主要存放各个系统的用户信息及登录的cookie信息。
2.保证各个系统的用户数据一致性和独立性。
各个系统拥有自己的用户数据表相互独立。每一个系统的CUD(创建,更新,删除)时都会触发其它系统的CUD。那么这里有个问题也会出现:各个系统登录无非就验证用户名和密码,所以就得保证各个系统的至少登录名、密码的一致性,可是各个系统可能处理密码时都有各自的方法,有的系统直接使用明文,有的系统使用md5或者其它加密方式。这时在没完成单点登录构架时的各个系统中对那些不可逆密码的数据处理就基本不可能了。我想到这种最好处理方法是所有密码加密只能遵循其中一种不可逆的加密了,那些可逆或者明文的密码都可以转成这种密码处理方式,这样数据就可以同步了,当然如果出现两种不一样且不可逆的密码时貌似就想不到啥解决方案了。
3.当某一用户进入某一系统,且他还未完成任何一个系统登录的处理。
用户输入某一个系统的网址进来,该系统就必须检测当前这个操作的是游客还是系统用户,其实如果不是多系统单点登录的话,就这一个系统也是会通过cookie、session等之类东西去检测游客还是系统用户,但只局限于此站点的检测。因为我知道我压根就没有此站点登录过,所以就得去其它系统中检测我是否有登录过,通过检测我还是没有在任何地方登录过,所以我的登录只是一名游客。
根据以上的需求,应该是这样去处理:
输入网站进入某一系统的其实一个页面,该页面(我这里把页面=行为处理的Handler)需要做的事是:进入页面构造时就redirect到了sso站点且redirect时必须附上returnUrl,因为sso站点处理后需要再次回调到用户进入某一系统的页面,总不至于停留在sso站点,因为用户都不知道有sso站点这回事。redirect到sso站点后,sso站点页面第一步只需要看看sso站点是否有登录的cookie信息,因为用户根本就没登录,所以肯定就不存在这个cookie值了,所以说明在其它系统我们没登录过,那么就得告诉用户进入的某一系统没有登录了,根据returnUrl并附带一个空的Token(如Token=$,$代表空)跳转到用户原来要进入的某一系统的页面,其实这时用户进入的还是原来的页面只是该页面附带了一个空的Token。页面看到了有一个Token参数,所以页面知道已经去过了sso站点检测且证明该用户在其它系统也是不存在登录的。要注意的是这里若不到Token,系统就死循环了哦!
4.用户在所有系统都未登录时,用户进入的某一系统完成用户登录的处理。
这里的登录有以下步骤进行处理:
1).某一系统根据用户登录的用户名、密码以后在自已对应的数据库中验证是否正确,正确说明登录成功了。
2).系统登录成功后就必须反馈给sso站点,那么这时应该怎么反馈呢?我的想法还是通过sso站点回调的方式去处理。某一系统登录成功以后其实根据需要得跳转到相关指定页面,这时拦截跳转页面并记录url并做为sso站点页面的returnUrl,sso站点处理授权登录的页面接受的参数不能只有一个returnUrl,至少还得告诉该页面是哪个用户进行登录了,否则去sso站点验证后怎么知道哪个用户登录了,但仅仅是一个用户名参数够了吗?我是觉得不够,这样也太不安全了,真那样我只要通过这个页面+用户名不是完成登录了?
本来我是这么想的:
sso站点授权页面得到三个参数(用户名,密码,returnUrl) ,sso站点需要向某一系统的用户数据表(各个系统的用户数据已经保持一致同步了)再次验证,在各系统数据同步正常的情况下验证其实肯定是成功的状态,成功后取出用户相关信息保存的缓存中,用户信息中也附带一个token值(唯一的),然后再在sso站点中生成一个cookie(存放的是一个token值), 同时这里的cookie和缓存信息失效时间需要设定一致。
后来是这么想的:
sso站点授权页面得到还只是两个参数(加密的用户名,returnUrl),当然这种加密是可逆的加密,但加密的key是会定时变化的,发送的这个加密的用户名,sso站点根据key解密得到用户名和生成一个token值(唯一的)存入缓存,然后再在sso站点中生成一个cookie(存放的是一个token值), 同时这里的cookie和缓存信息失效时间需要设定一致。
5.用户已经在某一系统中登录,但现在去了另外一系统,在该系统中还未完成授权。
因为现在去的这个系统其实还未完成登录,那么要得遵循3的步骤,构造去sso站点附带一个returnUrl,验证到了在sso站点有cookie信息,取出这个cookie值得到token,然后回调至已附带token参数的returnUrl页面,该页面判断token值存在后进入构造后的下步处理,该处理知道有token值后调用sso站点的api(webservice或者restful请求方式)得到用户名,根据这个名再从数据库中得到密码,并完成登录操作。
6.用户在某一系统登录后,每次需登录验证的页面请求会间歇性的向sso站点更改token值并完成延长cookie及缓存会话时间。
用户在长时间未操作时,可能访问的系统和sso系统会话结束时间不一致,这里我们只要保证sso或者系统会话时间只要一个未结束,就还会存在登录状态的。只有两方都没有会话时间的情况时才会跳转到登录页面要求登录。
7.用户在某一系统登录后,点击了该系统的退出
用户点击退出后,应实现某一个站点点退出所有站点全部退出功能。各站点可拥有自己的退出功能,某站点退出后再回调清除sso站点的缓存和一个sso所有站点退出页面,而sso站点应用应有一个退出登录的功能页面(聚集所有站点退出功能,批量回调各个实现退出),该功能可实现所有站点的退出