3. 同一域名中,各子域名下应用程序间实现SSO
要是这样的情况又将如何:Foo Bar两个站点运行在不同的域名下: http://foo.com and http://bar.foo.com. 上面的代码又不起作用了:因为cookie会存储在不同的文件中,各自的cookie对其它网站不可见.为了能让它起作用我们需要创建域级cookie,因为域级cookie对子域名都是可见的!这里我们也不能再使用 RedirectFromLoginPage 方法了,因为它不能灵活的创建域级cookie我们需要手工完成这个过程!
HttpCookie cookie = new HttpCookie(".BarAuth");
cookie.Value = FormsAuthentication.Encrypt(fat);
cookie.Expires = fat.Expiration;
cookie.Domain = ".foo.com";
HttpContext.Current.Response.Cookies.Add(cookie);
FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1, "John Doe", DateTime.Now, DateTime.Now.AddYears(1), true, "");
HttpCookie cookie = new HttpCookie(".FooAuth");
cookie.Value = FormsAuthentication.Encrypt(fat);
cookie.Expires = fat.Expiration;
cookie.Domain = ".foo.com";
HttpContext.Current.Response.Cookies.Add(cookie);
注意cookie.Domain = ".foo.com";注意这一行.这里明确指定了cookie的域名为".foo.com",这样我们就保证了cookie对 http://foo.com 和 http://bar.foo.com 以及其它子域名都是可见的.(译者注:cookie的域名匹配规则是从右到左) .你可以通过设置Bar站点的认证cookie的域名为"bar.foo.com".这样对于其它子域名的站点它的cookie也是不可见的,这样安全了.注意 RFC 2109 要求cookie前面有两个周期所以我们添加了一个过期时间.(cookie值实际上是一个字符串,各参数用逗号隔开).
再次提醒,这里还是需要统一一下各个站点的Web.config的<machineKey>配置节的Key值. 这种解决方案只有一种异常的情况,且看下节详解.
4. 运行在不同版本.Net下应用程序间实现SSO
要是Foo和Bar站点运行在不同的.Net环境中上面的例子都行不通.这是由于Asp.net 2.0使用了不同于1.1的加密算法:1.1版本使用的是3DES,2.0是AES.万幸,Asp.net2.0中有一个属性可以兼容1.1:
设置decryption="3DES"就会让 ASP.NET 2.0使用旧版本的加密算法使cookie能够正常使用.不要企图在Asp.net1.1的Web.config文件中添加这个属性,那会报错.