ASP.NET子域Cookie(父域和一个子域)

11

我有一个带有多个子域的应用程序,例如subone.parent.com、subtwo.parent.com。

我在parent.com/login上有一个登录页面。当用户登录后,根据其所属的子域重定向到相应的域名。这个功能运转良好。

FormsAuthenticationTicket ticket = new FormsAuth...
string encTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
cookie.Domain = subone.parent.com
Response.Cookies.Add(cookie)

这样可以正确地为subone.parent.com的用户进行身份验证,但不适用于subtwo.parent.com的用户。然而,我希望能够实现以下功能:

如果用户返回parent.com,则我想知道他们已登录并将其重定向回subone.parent.com。

是否有一种最佳实践来实现这一点?还是我必须为parent.com设置另一个cookie?

我在使用asp.net mvc,如果有影响的话。

谢谢!

3个回答

6
您可以像您尝试的那样在跨域之间共享cookie,但这并不是一件简单的事情,例如这里的例子。
另一个选择是将cookie设置为".parent.com",而不是明确指定子域,并使用cookie存储子域的详细信息。然后,您可以从任何子域(以及假设其为www.parent.com的父域)访问cookie。
如果您正在使用MVC,您可以很容易地创建一个自定义过滤器,并将其添加到www.parent.com控制器中以检查cookie是否存在,如果存在,则重定向到cookie指定的子域。有关过滤器的更多详细信息,请参见此处

我觉得这里的第二个选项可能会起作用。我将域设置为父级。我已经将子域添加到FormsAuthTicket用户数据中。我创建了一个CustomIdentity,它将在IsAuthenticated时检查当前域与用户数据的匹配情况。你觉得怎么样? - Paul

0

您可以在所有子域上共享同一会话。这是我们用来实现的代码 :-)

void MasterPage_Unload(object sender, EventArgs e)
{
   ///ASP.NET uses one cookie per subdomain/domain,
   ///we need one cookie for _all_ subdomains.
   if (Context.Response.Cookies["ASP.NET_SessionId"] == null)
      return;

   var sessionCookie = new HttpCookie("ASP.NET_SessionId", Context.Session.SessionID);
   sessionCookie.Domain = ".yourdomain.com" ; 
   Context.Response.SetCookie(sessionCookie);
 }

在 Page_Load 方法内部是:

 Unload += MasterPage_Unload;

它运行得非常好 :-)

罗伯特


谢谢Robert,但我不想让用户在所有子域上进行身份验证,只在一个和根目录上进行。 - Paul
我们在使用这个解决方案时遇到了一个严重的问题:它会阻止所有使用该代码的MasterPage页面上的OutputCache正常工作。这个解决方案OutputCache像魔法一样正常工作。 - Oliver

0

我会像你在那里设置显式域的cookie一样,因为这可以在特定域的cookie中保留任何安全信息。您还可以在*.parent.com级别添加一个非加密cookie,其中包含已经过身份验证的域的信息。但是,没有真正的方法将其联系起来,除非使用时间戳并在应用程序之间建立逻辑连接(即- sub2具有20分钟的会话超时,因此如果域+有效时间戳出现在父Cookie中,则它将有效,但这是业务逻辑)。

我不确定域之间断开的原因,但实际上你可能更喜欢具有加密文本背后的单个cookie。例如:

1)Sub1登录, 将parent.com cookie设置为有效。将用户数据发送到身份验证Web服务。

2)身份验证服务识别发件人为sub1,加密用户数据,并将其添加到自定义cookie对象中。

3)自定义cookie对象在唯一的拆分字符(或序列)上构造一个复合字符串,并使其对服务方法可用。

4)服务使用表单加密加密整个票证,并将其发送回原始登录页。

这样每个服务器都可以解密全局票据,但是每个数据块都会使用相同的算法进行加密,基于服务器的盐值。因此,如果子2尝试从子1读取cookie数据,则会得到加密版本而不是原始数据。


谢谢,如果我在.parent级别添加一个未加密的用户cookie,那么它不会被篡改/欺骗以允许访问其他子域吗? - Paul
@Paul:有点像。我建议使用两个级别的加密。第一个是默认的FormsAuthentication加密,它将整个cookie保持私有,仅限于*.parent.com域。第二个是对cookie的每个私有部分应用的内部加密,其盐只在主服务器和各个服务器之间知道。每个子域都可以访问整个cookie,但它们无法解密属于不同子域的部分。FormsAuthentication.IsAuthenticated将返回“true”值。 - Joel Etherton
@Paul:继续--记住,您需要使用某些东西来验证实际cookie中的数据。IsAuthenticated && MyCookieData.IsValid(ticket) 或类似的内容。 - Joel Etherton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接