当前位置:   article > 正文

天幻网FFSKY多域单点登录SSO系统的实现(基于.net)

天幻网

原作2006 年6月15日,运行了3年了,一切正常。转自我的MSN SPACE,包括评论的补充

天幻网FFSKY多域单点登录SSO系统的实现
Chocobo( http://www.ffsky.com)转载请保留~

    天幻网新的规划中,将涉及到多域,如FFSKY.COM,FFSKY.CN等等,因此网上某些对同一域靠设置COOKIE的DOMAIN=".FFSKY.COM"的方式根本行8通,因此考虑用纯粹的PASSPORT的机制。
    建设此系统前,我做了充分的准备工作,参考了网上N多的SSO系统实现的文章,包括国内和国外的,发现SSO系统有许多都是商业版的,基于JAVA的有许多现成的开源项目,甚至有WEBLOGIC内置的。而基于.NET的最完善的似乎是MS的PASSPORT,但貌似用户信息全部要汇总到MS的PASSPORT网站,也就是说无法调用自己的用户数据库。另外还有现成的Discuz!论坛的PASSPORT,但只能用在两个站之间。还有一个基于.NET的SSO东东,但看了半天应该也是商业版的,要下载试用版还获取不要验证邮件- -b 郁闷之下自己动手,丰衣足食~
    自己所接触到的自有的SSO系统的网站其实有印象的就2个,一个是MOP,一个是CSDN,但似乎都是同一域下的。看N篇参考文章之后唯一让偶感觉到可以在天幻实行的就是通过统一认证网站认证后返回到源网站,在URL地址中加入返回参数,而源网站通过解析该参数获取用户认证信息。这种方式可以跨多域.
    其基本流程是:用户登录某网站,点击“登录”,然后转向到认证服务器(PASSPORT),在认证服务器完成认证后携带加密后的参数转回到原网站,原网站解析加密信息后给予用户已经登录状态。
    但是网上很多资料都没有说清楚几点,正如我前一篇开工前文章中所说的:
   1、TICKET加密方式,DES还是RSA
   2、用户注销操作怎么处理,在A域超时,消息肯定要给S验证域,那当时用户还在B域里玩也,到底算他注销不。
   3、用户从A域转到B域,是否还要到S验证域验证一下。还是在用户登陆时就将信息发给各服务域。
   4、按SAML协议标准,有一个环节居然是服务域和注册域交互验证。这和原先的SSO流程不符合,看来可能还需要开发一个WEBSERVICE来遵循这个协议。
  
   而我设计的天幻的SSO流程中,对以上几点是这样处理的:
   1、使用AES衍生的Rijndael处理,因为DES强度太差,而且只有密钥,而RSA虽然有公钥和私钥,但生成的数据长度实在太长,不利于在浏览器中携带。而Rijndael算法有一个密钥和一个IV向量,可以在其中做双重验证用。
   2、注销操作没办法做到各域同步,忽略这一问题,由各域自己控制用户超时量
   3、引入自动监测机制,每张需要验证用户的页面如果发现用户没有登录,自动到PASSPORT域转一圈作为验证,如果在PASSPORT域发现用户已登录,则设用户已登录状态。
   4、由于采用Rijndael加密,为了最大化安全性,将IV作为服务主机和认证主机之间私密交换的信息,我采用的是WEBSERVICE方式。
  
   明确了以上的要素,整个单点登录系统就相对明确了。懒得画图,直接文字叙述实现方式吧,也不贴代码了,因为代码没有优化过,比较难看,同时也为了保证安全性,呼呼
  
   1、自动判断是否登录流程
  
     某可能会判断用户是否登录的页面,如果发现用户用户未登录(我都是判断SESSION(“NAME”)是否为空),并且用户浏览器支持COOKIE(即支持会话),且SESSION(“AUTOLOGIN”)为NULL, 则先置用户SESSION(“AUTOLOGIN”)=“1”,然后自动将用户重定向到PASSPORT域进行鉴别,如果未登录,则直接返回,如果已登录,则重定向回的URL地址中加载认证字串。 为了防止用户每点一张页面都要到登录域验证,所以需要加载一个认证是否已验证过的SESSION,以及浏览器是否支持SESSION。
     其中唯一的隐患在于ASP.NET碰到用户浏览器虽然支持COOKIE功能但用户手动关闭COOKIE的话无法判断。但相信这种情况不会太常见,而通常非注册用户访问页面张数也不会超过10张,所以即使存在此类问题对服务器压力也会比较小。
    
   2、子站点涉及的参数
  
      我给每个子站点分配一个SITEID和一个密钥,他们是一一对应的。为什么要给每个子站点分配不同的?因为这样就能引入第三方开发的程序,而无需由第三方来读取网站数据库。同时也可以防止第三方程序密钥泄露造成可以模拟用户登录。
      子站点在转到登录域的时候需要携带两个必要参数:SITEID和要转回的URL地址。SITEID用来让登录域判断要加密时使用的密钥(KEY),转回URL地址用以转回源地址用。
     
   3、基本登录流程
  
       在某子站点“登录”,转到登录域,登录域判断用户未登录(判断依据下述),要求用户输入必要信息(用户名/密码/是否记忆密码/验证码等),用户登录成功后写以下COOKIE信息:用户名、用户ID,用户IP、当前的SESSIONID、COOKIE有效时间(通常为几个小时)。然后用Rijndael算法,以当前的SESSIONID作为IV量,以对应该网站的KEY作为密钥,加密用户名、用户ID、IP、是否自动登录等等信息。同时,在数据库ONLINEUSER表中将登录信息插入数据库,保存登录人登录状态的SESSION,其实就是保存IV值。将加密后的字符串,连带用户的USERID作为TICKET参数返回给请求的网站,格式样本如下:
       http://www.ffsky.cn/index.aspx?ticket=38_4bku80WzbgHpgk034Wy5pOc%2f4cpIRI%2fLDHKDqITstQM%3d
       其中38即为我的用户名CHOCOBO在数据库的ID号。      
       而FFSKY.CN网站判断我在未登录状态,且QUERYSTRING有TICKET参数,则开始尝试解析TICKET参数。首先就是提取USERID和加密后字符串,然后调用PASSPORT认证网站中的一个WEB SERVICE,这个WEB SERVER传入USERID后即会从数据库中读取并返回用户最近的SESSIONID,即IV值。FFSKY.CN网站靠分配给它的密钥和通过WEB服务得到的IV值即获取了我的相关信息。
       获取相关信息后还需要有一点,即防模拟URL登陆,这里用的方式是判断IP地址,即解析数据库中有登录时的IP,然后通过IP地址比对来判断用户是否状态有变。如果A登陆后B直接粘贴A的URL地址是无法正常登陆的. 但同一内网的人如果这样做会怎么样呢?猛一看貌似比较难解决,但这里就需要用到一个小技巧了,就是一些牛X哄哄的安全公司用的一次密码技术。我们在调用WEBSERVICE是否,在WEBSERVICE传会IV值后即将数据库中对应的IV值置空。也就是说这个KEY只能用一次,这样问题就迎刃而解了。
       
   4、基本注销流程
  
      注销流程其实应该分两个环节,子站注销和验证域注销。流程相当简单,先到子站的LOGINOUT。ASPX,在子站销毁SESSION,再重定向到验证域,在验证域销毁COOKIE中关键信息(USERID/当前SESSIONID等),在数据库中删除相关登录信息,再转回到原子网站。
  
5、自动登录
  
     如前所述,用户访问某页面时自动会转到验证域判断是否登录过,而这时如果在验证域发现用户COOKIE中含有PASSWORD通过MD5加密过的信息,则会尝试自动登录机制。同时,如果用户在近期登录成功,即在COOKIE中有USERID信息,则尝试判断该COOKIE是否有效果,判断依据是看IP地址和COOKIE有效期,这里强置两点:1是IP地址必须和初始登录时一致,2是用户首次登录12小时后必须重新登录。如果一切PASS,则重新加密信息后转回请求页。
     
   6、安全考虑
  
     其实安全性主要有以下几方面攻击情况要考虑:
     1)、暴力破密码:
        在登录页加图片验证码,图片可以加强噪点等混淆机制,甚至可以将验证域用HTTPS方式。
     2)、模拟COOKIE:
        能获取某用户COOKIE信息有两类情况:掌握用户主机控制权,通过论坛等地方获取用户COOKIE部分参数内容(跨站攻击)。前者的话已无安全控制可言,而后者由于已经采用单一的域登录,理论上应该不可能通过跨站手法获取访问用户的COOKIE信息了。
     3)、取得密钥模拟:
        一是各子域密钥不同,二是采用Rijndael算法还有个IV量必须通过WEBSERVICE才能获取。两道锁应该比较安全了。
     4)、模拟登陆URL地址
        正如前面所述,通过一次密码的方式在WEBSERVICE中读取SESSIONID(即IV)后即将此值在数据库中去除。这样就可以防止第二方截取URL地址模拟登陆了。  
  
   结语:以上方式基本实现了天幻的SSO系统,其中还有很多小的编程细节和经验说也说8清楚,比如URL编码、取消自动登录、WEBSERVICE的IP验证……等等。此文仅描述流程部分,其中有许多是安全关注的焦点,编程部分还是看需要人的实力吧。这里就不做开源了,免得网站被无谓的攻击 ~O~ 发现以上流程有安全隐患漏洞的请留言,呼呼
    
仲仓戟 的图片
仲仓戟(离开) 发表:
1、用户从A域登录通过S验证域验证可正常访问A域后,链接到B域或者通过地址栏直接访问B域,正常情况下不需要用户再次登录B域,但我感觉用户在B域没有任何用户信息(哪怕是用户ID)可以和S验证域进行验证,似乎行不通啊!是不是我还没理解到你的实现方法,能否就此描述一下细节流程?
答:我采用的方法是,登陆B域,B域发现用户没有登陆过,则将用户自动重定向到S域,在S域通过COOKIE(SESSION已过期)或SESSION验证后再定向回B域实现B域自动登陆.如果重定向一次后还是没有登陆(说明用户原本就没登陆),则给用户在B域设置SESSION,在B域访问下一个页面时就不需要再去S域一次了.
2、“注销操作没办法做到各域同步,忽略这一问题,由各域自己控制用户超时量”,是不是说该实现方法出现以下情况是正常的:A域、B域、S验证域都留下登录COOKIE后,如果用户从A域注销,则A域、S验证域都被注销了,而B域还没有注销可正常访问,只是从B域切换到其他域时就要跳转到S验证域登录页面提示重新登录?如果是这样,最后这次S验证域的登录和此前的B域登录COOKIE信息是否会有冲突?
A域和B域用的是SESSION控制,不留COOKIE,S验证域留COOKIE保证长时间可在线.如果其他域都注销,而B域还没注销,从B再到A的话同样在S域会验证一次,但由于用户访问B域根本不需要通过S域验证了,原本就已经登陆,因此不存在冲突的问题.

进一步想,是否可以考虑S验证域记录下用户单点登录后所访问的其他域的信息,同时每个域都有自己的一个注销webservice,当用户从任何域注销的时候,由S验证域根据用户访问域记录主动逐一发起对应域的注销。请Chocobo一起来考虑这个方法的可行性。
答:主动发起注销是可行的,事实上我部分域里就设置了WEBSERVICE,用来同步一些信息,比如论坛的名称/社团的名称等.但如果域多了,注销时间就会很长,而一般服务器SESSION超时时间都设置为20分钟,关闭浏览器就自然试销,因此只要确保S验证域注销就可以了.
3、还是注销的问题,就是当用户不注销直接关闭浏览器时,因为各域的COOKIE时长不同,可能还有不少在用户再次登录的时候还没有过期,是否会引起最近一次登录后访问各域出现问题?
答:不会的,因为各域除了S域其他都是通过SESSION来控制用户,SESSION在用户关闭浏览器后就会注销.再开浏览器相当于用户没有登陆过该域.整个登陆流程和之前正常情况是一致的.
我在近几个月已经开了好几个子站了,虽然处于同一台服务器上,但分开放服务器也没有影响.http://sd.qiak.com,数独子站;http://www.ffsky.cn,专题子站;http://bbs.ffsky.com,论坛子站;http://www.duose.com,多色相册;http://www.qiak.com,恰客社团.用下来没什么问题,碰到的部分问题也是在流程中对后台数据库操作的问题,对流程没有大的问题.
8 月 24 日
匿名 的图片
marmot 发表:
Chocobo,拜读了你的文章,思路还不是很清楚,请进一步指教以下问题:
1、用户从A域登录通过S验证域验证可正常访问A域后,链接到B域或者通过地址栏直接访问B域,正常情况下不需要用户再次登录B域,但我感觉用户在B域没有任何用户信息(哪怕是用户ID)可以和S验证域进行验证,似乎行不通啊!是不是我还没理解到你的实现方法,能否就此描述一下细节流程?

2、“注销操作没办法做到各域同步,忽略这一问题,由各域自己控制用户超时量”,是不是说该实现方法出现以下情况是正常的:A域、B域、S验证域都留下登录COOKIE后,如果用户从A域注销,则A域、S验证域都被注销了,而B域还没有注销可正常访问,只是从B域切换到其他域时就要跳转到S验证域登录页面提示重新登录?如果是这样,最后这次S验证域的登录和此前的B域登录COOKIE信息是否会有冲突?

进一步想,是否可以考虑S验证域记录下用户单点登录后所访问的其他域的信息,同时每个域都有自己的一个注销webservice,当用户从任何域注销的时候,由S验证域根据用户访问域记录主动逐一发起对应域的注销。请Chocobo一起来考虑这个方法的可行性。

3、还是注销的问题,就是当用户不注销直接关闭浏览器时,因为各域的COOKIE时长不同,可能还有不少在用户再次登录的时候还没有过期,是否会引起最近一次登录后访问各域出现问题?

很希望将您的经验应用上,所以提了以上问题,请不吝赐教!衷心谢谢!
8 月 23 日
匿名 的图片
陆行鸟Chocobo 发表:
客户端SESSION仅是举例,也可以用.NET的IDENTY等方式.只要是判断用户是否登陆即可.作为客户端,只要判断用户是否登陆,如果没有的话转到验证域,解析验证域返回的字符串,通过WEBSERVICE获取IV量再验证,如果验证通过则设该用户为登陆.
6 月 17 日
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/138402
推荐阅读
相关标签
  

闽ICP备14008679号