asp.net 多子域名实现单点登录
作者:sithere 日期:2007-04-23
网站有bbs.xxx.com / main.xxx.com / pay.xxx.com 这三个不同的二级站站,要实现任何一二级域名处登陆,其他各二级域名的站均登陆。
解决办法:
设置cookie的domain属性。
详细介绍:
把保存用户登陆信息的cookie的域设置成一样即可。
usercookie.Domain=".xxx.com"; 要注意,在域名前必须要加一个"."。
这个设置在登陆和退出的时候都需要。
比较普遍的做法自然是用一个专门负责用户登陆的类来管理这些事务。这样其他登陆页面只要调用这个类就可以,一通百通。
而如果你使用asp.net 2.0 和forms验证,则有更简单的办法来完成这个设置。
web.config中添加了对域的支持,只要按照如下的设置即可:
程序代码
<authentication mode="Forms">
<forms loginUrl="Login.aspx" domain=".xxx.com" name=".AutoLinkEduSiteCookie"/>
</authentication>
<forms loginUrl="Login.aspx" domain=".xxx.com" name=".AutoLinkEduSiteCookie"/>
</authentication>
domain:可选的属性。
指定在传出 Forms 身份验证 Cookie 中设置的可选域。此设置的优先级高于 httpCookies 元素中使用的域。
此属性是 .NET Framework 2.0 版中的新属性。默认值为空字符串 ("")。
注意
无论是哪一种办法,cookie的name一定要相同。
引用内容
所谓的单一登录是指用户在一个站点如www.studyez.com登录后切换到另一个站点communty.studyez.com时也自动被community的Server判断为已经登录,反过来,只要用户在community.studyez.com登出后,切换到www.studyez.com时后www的Server也会判断到这一用户已经登出。
限制条件:
1.所有要求单点登录的站点间共享同一用户数据库,这点应该不需要任何解释的吧。
2.要求所有站点在同一父域名之下。这里所说的单点登录是指在同一个域名下不同子域名之间的单点登录,直接的例子就是像这样的站点之间的跨站单点登录: www.studyez.com, community.studyez.com, serach.studyez.com, mail.studyez.com, mms.studyez.com 等,他们属于一个共同的父域名studyez.com, 之所以有这么多子域名,是因为有很多子系统的时候用不同的子域名对于开发、部署和管理都能方便很多,而且对于用户访问量很大的站点,可能每个子域名都会有很多的服务器来伺服。这是比较符合目前很多站点的模式和需求的。
对于非同一父域名下的域名间跨站登录,最好的方式是采用Passport的原理来实现,具体实现可以参考Passport文档,因此不在本文讨论范围之内。
原理:
在不同的子域名之间实现单点登录的最佳途径是采用Cookie的Forms认证。他的原理简单的来说,就是让Forms Authentication生成的Cookie能够跨域名访问。
先谈一下Cookie的限制,对于一个任何Http Request来说,提交给Server端的时候,它能够安全访问的Cookie的域名必须在这个HTTP Reuqest的域名路径中。举例来说,发出一个http://communiy.corp.studyez.com/的请求时,随着这个http request一块发送到server端的cookies会自动包括所有以 community.corp.studyez.com, .corp.studyez.com, corp.studyez.com, .studyez.com, studyez.com为域名的Cookies,这是由Cookie本身的规范所限制的,浏览器如果不是按照这个规范实现,那么就会存在严重安全漏洞,因为那样的话意味着任何一个服务器都可以读到同一个用户访问别的网站时留下的Cookie。
根据上面所述Cookie的限制性,可以得出,对于前面www.studyez.com, community.studyez.com等站点的例子来说,就是想办法如何让Forms Authentication生成的Cookie的域名限定为.studyez.com或者studyez.com,而不是默认的www.studyez.com 和 communty.studyez.com,这样就使得单一登录需求的实现成为可能。
今天先写这么多,接下来几天会继续写实现和局限性。
限制条件:
1.所有要求单点登录的站点间共享同一用户数据库,这点应该不需要任何解释的吧。
2.要求所有站点在同一父域名之下。这里所说的单点登录是指在同一个域名下不同子域名之间的单点登录,直接的例子就是像这样的站点之间的跨站单点登录: www.studyez.com, community.studyez.com, serach.studyez.com, mail.studyez.com, mms.studyez.com 等,他们属于一个共同的父域名studyez.com, 之所以有这么多子域名,是因为有很多子系统的时候用不同的子域名对于开发、部署和管理都能方便很多,而且对于用户访问量很大的站点,可能每个子域名都会有很多的服务器来伺服。这是比较符合目前很多站点的模式和需求的。
对于非同一父域名下的域名间跨站登录,最好的方式是采用Passport的原理来实现,具体实现可以参考Passport文档,因此不在本文讨论范围之内。
原理:
在不同的子域名之间实现单点登录的最佳途径是采用Cookie的Forms认证。他的原理简单的来说,就是让Forms Authentication生成的Cookie能够跨域名访问。
先谈一下Cookie的限制,对于一个任何Http Request来说,提交给Server端的时候,它能够安全访问的Cookie的域名必须在这个HTTP Reuqest的域名路径中。举例来说,发出一个http://communiy.corp.studyez.com/的请求时,随着这个http request一块发送到server端的cookies会自动包括所有以 community.corp.studyez.com, .corp.studyez.com, corp.studyez.com, .studyez.com, studyez.com为域名的Cookies,这是由Cookie本身的规范所限制的,浏览器如果不是按照这个规范实现,那么就会存在严重安全漏洞,因为那样的话意味着任何一个服务器都可以读到同一个用户访问别的网站时留下的Cookie。
根据上面所述Cookie的限制性,可以得出,对于前面www.studyez.com, community.studyez.com等站点的例子来说,就是想办法如何让Forms Authentication生成的Cookie的域名限定为.studyez.com或者studyez.com,而不是默认的www.studyez.com 和 communty.studyez.com,这样就使得单一登录需求的实现成为可能。
今天先写这么多,接下来几天会继续写实现和局限性。
程序代码
// 用户 Cookie 存储键
public const string CookieUser = "devin_cn_user";
// 用户Cookie名称键
public const string CookieUserName= "UserName";
/// <summary>
/// 设置用户 Cookie 信息
/// </summary>
/// <param name="UserName">用户名称</param>
/// <param name="CookieSave">Cookie有效时间选择值</param>
private void SetCookie(string UserName,int CookieSave)
{
//设置Cookie值
HttpCookie cookie = new HttpCookie(CookieUser);
//设置域Cookie
cookie.Domain = ".devin.cn";
//设置用户名称
cookie.Values.Add(CookieUserName, UserName);
//设置Cookie身份验证码
cookie.Values.Add(CookieUserCode, this.CookieCode().ToString());
//根据选择,设置Cookie有效时间
switch (CookieSave)
{
case 0:
cookie.Expires = DateTime.Now; //即时
break;
case 1:
cookie.Expires = DateTime.Now.AddDays(1); //一天
break;
case 2:
cookie.Expires = DateTime.Now.AddDays(7); //七天,一周
break;
case 3:
cookie.Expires = DateTime.Now.AddMonths(1); //一月
break;
case 4:
cookie.Expires = DateTime.Now.AddYears(1); //一年
break;
}
//在保存 Cookie 信息之前,删除原有Cookie信息以避免重复
HttpContext.Current.Response.Cookies.Remove(CookieUser);
//保存Cookie信息
HttpContext.Current.Response.SetCookie(cookie);
//登陆认证
FormsAuthentication.RedirectFromLoginPage(UserName,false);
}
就是这一句吧
//设置域Cookie
cookie.Domain = ".devin.cn";
public const string CookieUser = "devin_cn_user";
// 用户Cookie名称键
public const string CookieUserName= "UserName";
/// <summary>
/// 设置用户 Cookie 信息
/// </summary>
/// <param name="UserName">用户名称</param>
/// <param name="CookieSave">Cookie有效时间选择值</param>
private void SetCookie(string UserName,int CookieSave)
{
//设置Cookie值
HttpCookie cookie = new HttpCookie(CookieUser);
//设置域Cookie
cookie.Domain = ".devin.cn";
//设置用户名称
cookie.Values.Add(CookieUserName, UserName);
//设置Cookie身份验证码
cookie.Values.Add(CookieUserCode, this.CookieCode().ToString());
//根据选择,设置Cookie有效时间
switch (CookieSave)
{
case 0:
cookie.Expires = DateTime.Now; //即时
break;
case 1:
cookie.Expires = DateTime.Now.AddDays(1); //一天
break;
case 2:
cookie.Expires = DateTime.Now.AddDays(7); //七天,一周
break;
case 3:
cookie.Expires = DateTime.Now.AddMonths(1); //一月
break;
case 4:
cookie.Expires = DateTime.Now.AddYears(1); //一年
break;
}
//在保存 Cookie 信息之前,删除原有Cookie信息以避免重复
HttpContext.Current.Response.Cookies.Remove(CookieUser);
//保存Cookie信息
HttpContext.Current.Response.SetCookie(cookie);
//登陆认证
FormsAuthentication.RedirectFromLoginPage(UserName,false);
}
就是这一句吧
//设置域Cookie
cookie.Domain = ".devin.cn";