ASP.NET2.0

网站开发

针对分析单点登录(流程图与数据安全)提出的问题及解决方案

    上一篇本人根据园友的文章:[原创]单点登陆(SSO)组件的设计与实现,根据自己的理解进行一次总结性的分析:分析单点登录(流程图与数据安全).

    当时根据SSO的流程做下了个人分析,也得到不少园友的评论及帮助,可是可惜的是,没有一位园友提出我画的流程图中存在的问题.这也可是大家没有看明白我的图(本人不才).

    当时自认为在流程上以及业务逻辑上都没有太大的问题,至到有次和朋友谈到了SSO,当时我非常自豪的说出了SSO的流程及思路,他也非常认可,可是他的一个问题把我难倒了.

   他的问题是这样的:  

       如果用户A在联盟站点SiteA中通过了认证中心的认可.这样用户A的用户uid就会出现在认证中心中的线列表中.此时如果用户A重新打开一个联盟子站点SiteB,此时在联盟站点SiteB中如何确认这个用户的身份呢?按
理说这个用户A在联盟点SiteB中应该是登录状态.

   为此再次贴出自己理解的SSO流程图,并在图上附上了困扰我的三个问题.

  

  
      按照SSO登录流程来看(个人理解):

      首先:
            判断本站点的Session["uid"]是否存在,如果本站点的会话状态存在则说明是登录状态.
           
             问题:用session来管理子站点的会话状态,可以有效的减少子站与联盟站点的关联.但是当子站点的session过期后,此时的情况有可能是这样的,在子站点A中存在的Session没有过期,但子站点B中的Sesion 正好过期,而用户又没有通过正常的退出操作,此时如何控制认证中心的在线列表呢?是存在还是不存在呢?

      其次:
            如果Session["uid"]不存在,则判断网页参数中是否有uid这个参数,如果有则通过uid到认证中心中判断这个uid是否在认证中心的在线列表中,如果有则说明此用户是登录状态.不知道这样理解是否正确.
 如果是这样,那么问题是这样的:
            如果用户A登录成功了,此时用户B知道用户A网页上的参数uid,他人为的在其它子站点中的页面中加入这人参数,此时应该也会是登录状态.如何解决这个问题呢?

      还有一个问题就是我朋友提出的:
      如果用户A在联盟站点SiteA中通过了认证中心的认可.这样用户A的用户uid就会出现在认证中心中的线列表中.此时如果用户A重新打开一个联盟子站点SiteB,此时在联盟站点SiteB中如何确认这个用户的身份呢?不同
站点的Session是不能共享的.(如何知道是用户A登录而不是用户B呢?)按理说这个用户A在联盟点SiteB中应该是登录状态.

      本人分析:
      1:新打开的联盟站点是肯定不存在Session的,因为站点间Session是不能共享的.
      2:新打开的联盟站点是肯定不会存在用户的uid的.
      此时根本不能判断用户是否已经在认证中心中登录过.
     
    本文的焦点其实就在于联盟站点如何确认用户身份的问题.即如何确认用户的uid.

    经过本人的假想:我的解决思路是这样的,不知道实际应用中是否可行。
    
   
     用户A在站点SiteA中登录成功后,将用户的UID和用户IP以cookie的形式保存在客户端。当用户打开一个新的联盟子站点(例如SiteB)时,此时的判断用户状态的流程变成上图.一般用户的IP在一定时间内是唯一确定的,这样做应该可以保证用户身份的正确性与唯一性(个人是这样认为),不知道这样做是否正确.上面的流程图应该可以解决我在本文中的第一幅图中的三个问题。

    本人学艺不精,一直未对SSO有正确的理解,本人凭着对SSO的热情,希望能够通过和各位园友的热诚探讨来分析SSO的最佳方案.

posted on 2008-06-22 10:54 姜敏 阅读(2016) 评论(28)  编辑 收藏 所属分类: ASP.NET2.0

Feedback

#1楼  2008-06-22 11:05 jillzhang      

用session来管理子站点的会话状态,可以有效的减少子站与联盟站点的关联.但是当子站点的session过期后,此时的情况有可能是这样的,在子站点A中存在的Session没有过期,但子站点B中的Sesion 正好过期,而用户又没有通过正常的退出操作,此时如何控制认证中心的在线列表呢?是存在还是不存在呢?
-----------------------------------------------------------------
这些问题好像是想多了
我觉得思路是各自为政,尽最大限度降低耦合性,A站点过期,更新A列表,B站点过期更新B列表,联盟站点过期更新联盟站点,只要联盟站点不过期,登陆A或者B,都会自动创建会话。但如果联盟站点会话过期,但A,B站点没有过期,那肯定要删除联盟站点中的在线列表中的对应用户   回复  引用  查看    

#2楼 [楼主] 2008-06-22 11:13 姜敏      

@jillzhang
非常谢谢队长的回复
那就是说认证中心的存在多个在线用户列表了,它们根据站点编号来区别.
例如:
子站点A有一个在线用线列表ListA
子站点B有一个在线用线列表ListB   回复  引用  查看    

#3楼 [楼主] 2008-06-22 11:14 姜敏      

@jillzhang
能不能解释下我朋友提出的问题呢?
如果用户A在联盟站点SiteA中通过了认证中心的认可.这样用户A的用户uid就会出现在认证中心中的线列表中.此时如果用户A重新打开一个联盟子站点SiteB,此时在联盟站点SiteB中如何确认这个用户的身份呢?不同
站点的Session是不能共享的.(如何知道是用户A登录而不是用户B呢?)按理说这个用户A在联盟点SiteB中应该是登录状态.

本人分析:
1:新打开的联盟站点是肯定不存在Session的,因为站点间Session是不能共享的.
2:新打开的联盟站点是肯定不会存在用户的uid的.
此时根本不能判断用户是否已经在认证中心中登录过.   回复  引用  查看    

#4楼 [楼主] 2008-06-22 11:23 姜敏      

@jillzhang
这些问题好像是想多了
我觉得思路是各自为政,尽最大限度降低耦合性,A站点过期,更新A列表,B站点过期更新B列表,联盟站点过期更新联盟站点,只要联盟站点不过期,登陆A或者B,都会自动创建会话。但如果联盟站点会话过期,但A,B站点没有过期,那肯定要删除联盟站点中的在线列表中的对应用户
------------------------------------------------------
那就是说认证中心的存在多个在线用户列表了,它们根据站点编号来区别.
例如:
子站点A有一个在线用线列表ListA
子站点B有一个在线用线列表ListB
如果各自为政的话,那么当用户新打开一个子站点时,如何让这个用户在新 打开的子站点中保持登录状态呢?(如何用户在认证中心登录过)希望jillzhang针对#3楼的问题或者是我朋友提出的问题做下分析.这也是困扰本人多日的问题啊.   回复  引用  查看    

#5楼  2008-06-22 11:30 ymm [未注册用户]

跨域认证你可以看看discuz的通行证api。通过url加密的方式实现单点登录应用叫广泛。   回复  引用    

#6楼  2008-06-22 11:38 王孟军!      

我不用过SSO,学习了,呵呵   回复  引用  查看    

#7楼 [楼主] 2008-06-22 11:42 姜敏      

@王孟军!
见笑了,本人认为jillzhang的SSO写的不错,就用了些时间去学习,只可惜现在有些问题还不是太明白,惭愧啊.   回复  引用  查看    

#8楼 [楼主] 2008-06-22 11:43 姜敏      

@ymm
discuz的东西看起来太费劲,不过还是谢谢指教.   回复  引用  查看    

#9楼  2008-06-22 14:27 Gray Zhang      

我的想法是这样的:
1.所有的登陆都跳转到登陆中心去登陆
2.在登陆中心登陆后,在客户端保存COOKIE(COOKIE的域是登陆中心的域)
3.所有联盟站点跳转到登陆中心时,用一定的方法(比如QueryString)告诉登陆中心登陆完成后的跳转页面
4.登陆中心登陆后自然要想办法告诉联盟站点有用户登陆
5.联盟站点自己想办法保存住用户的认证信息

6.当用户打开新的联盟站点并到达要求登陆的页面时,跳转到登陆中心
7.此时会把登陆中心的COOKIE带过去,所以登陆中心就知道用户已经登陆且用户名是什么
8.回到上面第4步,告诉联盟站点登陆的用户   回复  引用  查看    

#10楼  2008-06-22 22:27 acheqi      

楼主可以看一下sohu的通行证,看完了之后,你会发现,你这些问题,根本就不是问题,我现在基本上解决了,跨域名,跨平台,跨系统,而且每个系统的用户系统都可以独立运行,耦合性极低,有兴趣的话,大家可以一起研究   回复  引用  查看    

#11楼 [楼主] 2008-06-22 23:33 姜敏      

@acheqi
非常高兴得到您的指教,sohu的通行证,这个我倒是没有看过,它不是开源的吧?对于本文前面一幅图中提出的三个问题,您决的我后来的解决方案可行吗?   回复  引用  查看    

#12楼 [楼主] 2008-06-22 23:34 姜敏      

@Gray Zhang
您提出的方案和我后面列出来的解决方案有异曲同工之处,哈哈.   回复  引用  查看    

#13楼  2008-06-23 00:15 赖文华(SWPU小赖)      

学习中,
帮顶!   回复  引用  查看    

#14楼  2008-06-23 01:17 废墟中的垃圾      

@acheqi
sohu的通行证很简单,就是一个跨域设置cookie
本身IE的安全设置是不允许跨域设置cookie的,但是在http发送的head info 里面添加了一段安全认证的信息,那段信息可以往上搜索到。
然后就可以跨域设置cookie了。
但是还是没有特别好的解决,单一cookie丢失,这个站点登陆信息就丢失了这个问题。   回复  引用  查看    

#15楼  2008-06-23 04:40 废墟中的垃圾      

仔细看了一下文章,lz真的是很认真地考虑过了。
但是完全没有提出很好的方案。
因为同一个局域网内的多个用户是很正常的,有想过这个问题吗?
还有就是,你朋友的疑问完全可以通过sohu的方法解决。
而且如果使用了sohu的解决方案,那么你的其他问题也就迎刃而解,完全不需要那么多的考虑了。也就是无论你是session还是cookie,身份验证的过程都通过cookie来实现。
当然cookie里面具体保存什么就需要很认真地考虑了,安全性和可用性,lz可以考虑后得出结论。

我一直在做sso,有很多时候,有很多折中方案,也不是那么强求一定要一等都等。如果联盟无数呢?而且联盟无限扩展呢?sohu的解决方案还能成立吗?
答案当然是否定的。

所以呢,只要做到一定的好就可以了。
还有就是如果我们能很容易的获得mac就可以轻松验证登陆了。因为这里是相对唯一的。
还有一些其他的方法来进行更加人性化和安全的措施。   回复  引用  查看    

#16楼  2008-06-23 09:24 李战      

使用“特使协议”,可实现不同域名的联盟网站在浏览器客户端交换登录状态,无须往返服务器。“特使协议”支持跨域的Cookie交换,支持跨域的AJAX调用。

现在忙,过些天把实现细节告诉大家。   回复  引用  查看    

#17楼  2008-06-23 11:15 jillzhang      

你的第二个问题
用户B试图用伪造的方式来发起攻击

我的解决方案中已经有了应对策略。
站点A和站点B所持有的公钥和私钥都是不同的,尽管用户B知道用户A在站点A中的uid,没有关系,因为本身uid就是公开的信息,就像人的姓名一样,不是什么秘密,谁知道都无所谓,但在联盟站点和认证中心中传输这个明文要解决的问题不是保护uid,因为也说了嘛,uid是公开的,不是秘密,真正要解决的是认证中心和联盟站点之间的信任问题。也就是说只有认证中心发给联盟站点的uid,联盟站点才能接受,怎么样去建立这种信任关系,在技术中要使用的就是数字签名。如果用户B知道uid之后,想伪造登陆是不可能的,因为其没有认证中心和联盟站点各自持有的证书。   回复  引用  查看    

#18楼  2008-06-23 11:17 jillzhang      

还有就是如果我们能很容易的获得mac就可以轻松验证登陆了。因为这里是相对唯一的。
-----------------------------
的确是相对唯一的。
如果要保持比较高的安全性,原则是服务端不相信客户端的ip,mac等信息,因为这些信息太好伪造,但可以相信其签名信息。   回复  引用  查看    

#19楼  2008-06-23 11:24 jillzhang      

至于你的第三个问题,你的理解还是没有到位
-----------------------------------------------
我一直在强调,联盟站点,认证中心各自保持自己的会话。各自为证,彼此不相干,这也包括联盟站点与认证中心之间不公用会话,联盟站点与联盟站点之间都不会共享会话。
那么出现你说的这种情况,用户在联盟站点登陆了,并且在站点a登陆了。但并没有表示在b登陆了。要想访问b,还要走一个登陆流程。
用户访问B->没有会话->跳转到认证中心->有会话->生成答复发给b->验证答复->建立会话

当然里面本来有很多拐弯的地方,不能画图,就省略了   回复  引用  查看    

#20楼 [楼主] 2008-06-23 22:56 姜敏      

今天非常遗憾,等到了这么多园友的热情帮助,可惜本人今天白天不能上网,没能及时和大家沟通下.   回复  引用  查看    

#21楼 [楼主] 2008-06-23 22:57 姜敏      

@废墟中的垃圾
多谢您的指教,好方案   回复  引用  查看    

#22楼 [楼主] 2008-06-23 22:58 姜敏      

@废墟中的垃圾
我觉的您可能把跨域cookie的操作方法介绍下.最好是一下简单的demo   回复  引用  查看    

#23楼 [楼主] 2008-06-23 22:59 姜敏      

@李战
哈哈,具然得到了李老师的回复,哈哈,我太有才了,希望能够尽快的看到您的新作   回复  引用  查看    

#24楼 [楼主] 2008-06-23 23:00 姜敏      

@jillzhang
经过您的耐心指教,我的第二个问题总算是想明白了.多谢多谢   回复  引用  查看    

#25楼 [楼主] 2008-06-23 23:03 姜敏      

@jillzhang
至于你的第三个问题,你的理解还是没有到位
-----------------------------------------------
我一直在强调,联盟站点,认证中心各自保持自己的会话。各自为证,彼此不相干,这也包括联盟站点与认证中心之间不公用会话,联盟站点与联盟站点之间都不会共享会话。
那么出现你说的这种情况,用户在联盟站点登陆了,并且在站点a登陆了。但并没有表示在b登陆了。要想访问b,还要走一个登陆流程。
用户访问B->没有会话->跳转到认证中心->有会话->生成答复发给b->验证答复->建立会话

----------------------------------------
其实我没有想明白的就是您的登录过程,
用户访问B->没有会话->跳转到认证中心->有会话
这里的有会话,这是如何判断的呢,如何判断这个会话是我的而不是别人的呢?
  回复  引用  查看    

#26楼 [楼主] 2008-06-23 23:05 姜敏      

本人不才,望您悉心指教   回复  引用  查看    

#27楼 [楼主] 2008-06-23 23:06 姜敏      

1:新打开的联盟站点是肯定不存在Session的,因为站点间Session是不能共享的.
2:新打开的联盟站点是肯定不会存在用户的uid的.
此时根本不能判断用户是否已经在认证中心中登录过.

能否分析下我上面的分析过程呢   回复  引用  查看    

#28楼  2008-06-26 09:38 Herman.Wong      

呃.我觉得SSO有很多实现的方法.
我的那个是比较简单的.嘎嘎.   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-06-22 16:33 编辑过


相关链接: