今日偶然阅读了Understanding Single Sign-On in ASP.NET 2.0 这篇关于单点登录的文章,仔细阅读,发现还是有些不尽完整之处。

文中对于单点登录的介绍,忽略了一个重要问题——就是站点的域的问题。在深入讨论这个问题之前,先简单介绍一下网站域的概念,举个例子,假如我们有三个站点:
A: blog.joycode.com; B: beta.joycode.com; C: www.openlab.net.cn 。那么A站点的域是"blog.joycode.com",它的主域是"joycode.com";B站点的域是"beta.joycode.com",它的主域是"joycode.com";C站点的域是"www.openlab.net.cn" ,它的主域是"openlab.net.cn"。对于A和B来说,他们是不同的网站域,但是主域是相同的,都是"joycode.com",对于A和C来说,不管是域还是主域,都不相同。一般我们所说的单点登录,都是指A,B,C这三类站点可以在一点登录,实现所有的站点都不需要再次登录,甚至于不仅限于网站之间,也可能是从其他客户端到网站。一般比较大的系统都需要这样的单点登录系统,例如著名的微软的Passport,还有飞信的SSO。

回过头来看这篇单点登录文章,按照这种方案,仅能实现同一域下各虚拟目录的单点登录,离真正的单点登录还差得远,当然,文章的思路,对于同一域下的虚拟目录,或者同一主域的不同站点,还有有意义的。

前面说到了文章中的方案还只能实现同一域下的不同虚拟目录的单点登录,还不能实现同一主域的单点登录,那么怎么样才能在这个方案基础上实现同一主域的不同站点的单点登录呢?

文章的核心部分在于让每个站点的MachineKey保持一致,采用Form验证,这样可以保证每台服务器Cookie加密解密的结果是一致的。Form验证将登录后的授权凭证加密后保存在Cookie中,由于同一域下面的虚拟目录,Cookie是可以共享的,因此可以同一域内直接实现单点登录,而对于不同域,Cookie是不能直接共享的,所以对于不同域而同一主域的情况,我们还需要将Cookie的domain设为主域。那么还以前文的A、B站点为例,要实现单点,我们只要在web.config中,配置authentication \forms节点下domain值为主域,如下:
<authentication mode="Forms"> <forms loginUrl="login.aspx" name=".ASPXAUTH" domain="joycode.com"/> </authentication>
即可实现同一主域不同子域站点之间共享登录了。

而对于不同主域的站点,实现方案相对就复杂多了。