多站点整合—单点登录简单方案[SSO][转]

| | 2012/07/08 09:27 , mdy
PHP , 评论(0) , 阅读(2824) , Via 本站原创
Tags:
问题描述:在一个比较复杂的网站环境下。有多个产品向外提供服务。每个产品下都有自己的用户登录界面。现在需要设计一个统一的登录界面。当用户在这个界面登录后就可以自由的使用各个产品和服务。同时意味着用户用一个帐号可以在不同服务里登录,另一方面就是在一个服务里面登录后可以无障碍的漫游到其他服务里面去。

实际应用:Sohu的Passport将focus.cn,17173.com,sogou.com,chinaren.com这四个域名下的产品全部整合在一起了。用户在这四个站点中任何一个地方都可以登录。当用户登录后可以自由的使用其他域名下的服务。现在很多网站上都有bbs blog album服务。这些服务一般也是自己维护自己的用户信息。当发展到一定时候,也需要一个Passport机制整合所有服务,使用户可以单点登录。

Sohu的实现方案
在http://passport.sohu.com/ 登录后 fiddler可以拦截到如下的返回信息:

http://passport.sohu.com/sso/crossdomain_all.jsp?action=login 因为在同一个域名下,没有跨域,在这次请求中,上次成功登陆的cookie会被一并带着回去。服务器端检查到成功登录的cookie后会Render回一段同时登录多个站点的html。

http://passport.sohu.com/sso/crossdomain_all.jsp?action=login Render回来的script 请求同域下的http://passport.sohu.com/sso/crossdomain.jsp?action=login&domain=17173.com 这时passport.sohu.com下成功登录的cookie会被带回去。

在上面的过程中,最核心的技巧就是在指定的域下写入想要的Cookie:

1.  Sohu使用了在同一个域名登录后通过再次请求这个域名下某个链接后,得到要登录站点的请求Url,通过javascript使隐藏的iframe请求要登录站点的Url,服务器端接到请求Redirect到要登录站点,然后通过Response写入Cookie,完成跨域名写Cookie的操作。这种写Cookie的方式,需要在跳转时对请求的QueryString进行加密。接受方需要对QueryString进行解密。

2.  这种做法在服务器端不需要特别的处理。只要写好相应Post操作 WriteCookie操作 Redirect操作 就可以了。在FireFox下就可以正常工作了。但是在IE下写Cookie的操作还不行,总是写不进去Cookie。需要在Response中加入一段特别的Header. P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"

这个Http Header 是P3P安全的要求。P3P的详解 http://www.oreilly.com.cn/book.php?bn=7-302-07170-5
微软对这个的解释:http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q323752

一个更加轻量级的方案

Sohu的通行证方案已经可以轻松的将各个域名下的用户都同步登录了。但是在实现上Sohu会让客户端的浏览器请求两次passport.sohu.com。在第二次得到一个登录多个站点的地址列表。在第三次请求时通过本域下的cookie进行身份验证,最后在服务器端跳转到一个含有加密Key的其它域名的Url地址,最终写入登录成功的Cookie。除去最开始的登录,要求用户在登录后再进行两次请求。并且服务器端要再做一次跳转。Sohu的做法可能由于Sohu服务器环境和数据存储的结构所决定。

其实总共只需一次登录请求,和每个域名下一次请求就可以完成多站点登录了,同时也不需要服务器端的跳转。

两种方案的比较

1. Sohu使用的登录方式,请求次数多,但是每次请求都有对应的验证过程,在服务端跳转时,重要的跳转Url地址在HttpHeader中,使得跳转地址更加安全,使得用户在跨域登录时非常安全可靠。

2. 轻量级方案的登录方式,请求次数少,没有服务器端的跳转,对服务器压力小。但是需要对Key进行加密解密。跳转的Url会在Response的Http Body中Render给用户。在使用轻量级方案的时候,最好在Key中加上时间戳,过期时间设置为3分钟。Key过期认为这个Key是非法Key,不在Response中写入登录成功的Cookie。