当前位置:首页 > 开发 > 开源软件 > 正文

对单点认证的理解(不是讨论怎么解决)

发表于: 2006-01-03   作者:crazysoul   来源:转载   浏览:
摘要: 好比你去一个公园游玩,去到每个摊点时却又要你买一次票,是不是很麻烦? 而单点认证就是只要在门口买一次票后,只需在进去时要向摊主展示一下你的门票 ,同一个公园内的摊点就任意随你参观了。 即统一一个登录入口,经过验证后发给客户端一张"门票"作为买过票的评据,可以访问所有"公园设施",至于"门票"是怎么保存到游人手上(客户端)的,就是
好比你去一个公园游玩,去到每个摊点时却又要你买一次票,是不是很麻烦?
而单点认证就是只要在门口买一次票后,只需在进去时要向摊主展示一下你的门票
,同一个公园内的摊点就任意随你参观了。

即统一一个登录入口,经过验证后发给客户端一张"门票"作为买过票的评据,可以访问所有"公园设施",至于"门票"是怎么保存到游人手上(客户端)的,就是单点认证的核心难点。

很多人说用COOKIE。不错,在B/S模式中,COOKIE可以说是唯一合法的、能主动由服务器存放数据到客户端的途径(SESSION也是由COOKIE来保存SESSIONID的,若是临时的则由当前浏览器进程,SESSION和COOKIE的关系已在另一篇文章里讨论过了)。
但COOKIE有个限制,就是"跨域"问题,即一个站点只能控制以它的根域为名的COOKIE数据,如WWW.W3C.COM则只能控制W3C.COM这个域的COOKIE,其他如GOOGLE.COM、microsoft.com等的它都管不了。

当架设一个单点认证系统时,用户访问应用服务器A(AS.A),AS.A在自己的服务器上找不到有登记信息,则会导向到登录服务器(LS)为用户做登录认证,通过认证后,LS记录下用户的信息,并给AS.A发一个信息说"这个用户买票了",AS.A就在自己的服务器上接收LS传过来的复本作登记了(则以后不用每次都向LS查询),同时回馈给用户一张"票根"即认证根据(TOKEN ID),再把用户导向回AS.A,用户就可以到AS.A上进行他的活动了。

过了会用户在AS.A上玩厌了,想到隔壁的AS.B上看看时,AS.B也要问用户查看他的"票根",这时问题来了。

如果AS.A和AS.B是不同域的,一个是A.COM一个是B.COM,用户(USER)要访问AS.A则只要判断COOKIE里有没"票根"并根据这个"票根"来核对是不是他本人。
这个"票根"对AS.B也是通用的,只要向AS.B展示这个"票根"就行了。但问题正是,"票根"是在通过LS认证后,AS.A存放到A.COM的COOKIE里,而在访问AS.B时,AS.B是不能访问A.COM的COOKIE数据的,或者说它根本不知道A.COM的存在。
(注:A1.A.COM和A2.A.COM这样是同域的,都可以访问A.COM的COOKIE)

所以USER在访问AS.B时又要得到LS做一次认证,这就违反了单点认证的本意。
这就是COOKIE的跨域限制问题。



一个简陋的解决方案是在AS.A的每个连接上都追加一个TOKEN ID(类似&TOKENID=asrw34rzx242),当用户顺着这个连接到AS.B时,AS.B就能根据这个贴在用户脑袋后面的"票根"来向LS做认证查询了,若在LS上有对应TOKEN ID的合法信息存在,则也保留一份到自己的服务器上备用,并且也有样学样在每个连接上贴上这个"票根",好让用户顺着连接到别的"摊点"(AS.C、AS.D.....)上继续游玩。

但这种这方法实现很简单,但有很多缺点,如要求所有认证系统内的页面都要贴上一段TOKEN ID,即不美观又麻烦,而且,当用户不是顺着页面的连接,而是新开一个窗口来访问AS.B时,取不到TOKEN ID的值,也需要重新到LS认证一次。
所以这种做法只适合简单的会话型或一条龙服务型的。

还有一种做法是LS群发,即用户登录后,LS向所有在它名下所有登记的"摊点"都发一次通知,让他们自己做记录。如果用户无聊登录一下又马上退出又登录...,那LS就可能忙得不可开交了,接到通知的AS们也要跟着瞎闹个不停;又假设同时有100人登录,而园内有上100个摊点,LS就要发通知100X100次,真是一百遍又一百变;很有可能一个用户永远只去一个"摊点",其他的一次都没有去过,而其他的也要为他做登记,已供侯用户的"突击访问",这样就比较浪费资源和表情了。
所以这种做法也不是很妥当,适合园子比较小的:)
(后来认真想想也不行,就算每台服务器里都有登录信息了,但用户手上还是没有证明他身份的凭据:TOKEN ID,因此此方案否决!)

一种比较可行的方案:
借用这里了一个很巧妙的思路(纯指思路,代码不成熟)
http://blog.csdn.net/liyujie2000/archive/2004/03/11/13511.aspx?Pending=true

即在访问AS.B时,AS.B得不到TOKEN ID则不是主动向LS查询了,而是"悄悄"地引导客户到LS,再"悄悄地"由LS把客户的TOKEN ID帖到客户的脑后带回到AS.B,AS.B就可以根据根据带回来的TOKEN ID再向LS做一次验证(如此麻烦是为了防止欺骗,当然LS和AS.B之间的会话也要校验),这个过程是"瞒着"客户利用客户的浏览器(就是为了取回LS的COOKIE"票根")悄悄进行的,用户体验上最多在第一次访问时比第一次登录AS.A时慢一点,因为多了一步AS.B向LS校验的过程,但总的来说是简单可行的。
(注1:因为每次合法认证都需经过LS,所以LS的COOKIE是一定存在的,若不存在呢?废话,提示他登录咯。所以LS的COOKIE是这个跨域方案的基础)


能不能不用COOKIE呢?
这跟客户端的身份识别技术有很大关联,如果能确认唯一客户端,那就可以不依靠COOKIE了,这种技术也有不少,但都不是很方便,如客户证书等。另外有人说取用户的网卡的MAC值,如果你能用"合法"的手段做到,那么我也没意见的。


还有COOKIE的一个"伪造"和"顶替"问题(COOKIES欺骗),所谓"伪造"那是知道服务器生成COOKIE的格式和算法,伪造者再重新生成的一个COOKIE,如SERVER A的COOKIE的结构为:USERID = XXX;USERPASD = ****;TOKEN=ASD34AF23SDF3;
TOKEN是根据USERID和USERPASD再加上服务器的私钥生成的一段摘要,
而伪造者只有知道它的私钥和TOKEN的具体算法才能用任意的USERID和USERPASD来伪造一个合法的COOKIE。
而顶替呢,则只需要得到这段"USERID = XXX;USERPASD = ****;TOKEN=ASD34AF23SDF3;"完整的数据,根本不需要知道服务器的私钥和TOKEN的算法,只需把这段COOKIE发给服务器,在SESSION ID的有效期内就能冒充这个COOKIE本身的所有者来与服务器进行会话。
有些人对这两个概念老是混淆不清就一昧地说COOKIE不安全、容易被窃取,那只是看到"顶替"这一方面,但若要随意伪造COOKIE却不会那么容易,如果你能随意得到服务器的私钥(就算TOKEN的算法是公开的),那只能说是那台服务器的管理有问题,你把银行帐号的密码写到本子上锁到柜子里,而柜子被小偷撬开,根据密码到柜员机取走了钱,难道可以说是银行不安全吗?


相关讨论连接(有些思路不是完全正确的,不要随便盲从):
http://forum.iteye.com/viewtopic.php?t=11655&highlight=%BF%E7%D3%F2
http://forum.iteye.com/viewtopic.php?t=11582&highlight=%BF%E7%D3%F2
http://forum.iteye.com/viewtopic.php?t=6473&highlight=%BF%E7%D3%F2

对单点认证的理解(不是讨论怎么解决)

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号