表单身份验证,共享cookie问题

时间:2013-02-08 10:56:00

标签: asp.net cookies forms-authentication subdomain

我注意到使用共享身份验证Cookie设置的一些奇怪行为,这是我的方案。

我有两个类似于以下域名的应用程序:

login.mydomain.com system.mydomain.com

我正在将用户重定向到login.mydomain.com并从mydomain.com上删除cookie,就像这样。

system.mydomain.com:

void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        if (Context.User == null || !Request.IsAuthenticated)
        {
            HttpContext.Current.Response.Redirect("http://login.mydomain.com");
        }
    }

login.mydomain.com

protected void btnSubmit_Click(object sender, EventArgs e)
    {
        pnlLoginNotice.Visible = true;
        if (Membership.ValidateUser(txtUsername.Text, txtPassword.Text))
        {
            HttpCookie cookie = FormsAuthentication.GetAuthCookie(txtUsername.Text, chkRememberMe.Checked);
            cookie.Domain = "mydomain.com";

            Response.Cookies.Set(cookie);
        }
    }

Web.config:

<authentication mode="Forms" >
  <forms timeout="2880" name=".COMMONAUTH"  />      
</authentication>

现在我看到的行为是,我发现有时会在system.mydomain.com下删除.COMMONAUTH cookie,而mydomain.com下有相同的cookie。我注意到它在网站停用一段时间后就出现了。

asp.net是否可以自行删除cookie以保持表​​单身份验证的活动?

更新 我尝试了以下方法

1

system.mydomain.com Web.config

<authentication mode="Forms" >
  <forms timeout="1" name=".COMMONAUTH" />      
</authentication>

login.mydomain.com Web.config

<authentication mode="Forms" >
  <forms timeout="2"  name=".COMMONAUTH"/>
</authentication>

在一分钟后刷新system.mydomain.com中的页面时,我在system.mydomain.com下获得.COMMONAUTH cookie

2

system.mydomain.com Web.config

<authentication mode="Forms" >
  <forms timeout="2" name=".COMMONAUTH"  />      
</authentication>

login.mydomain.com Web.config

<authentication mode="Forms" >
  <forms timeout="1"  name=".COMMONAUTH"/>
</authentication>

在一分钟后刷新system.mydomain.com中的页面时,我会被注销。

第3:

system.mydomain.com Web.config

<authentication mode="Forms" >
  <forms timeout="1" name=".COMMONAUTH" domain="mydomain.com" />      
</authentication>

login.mydomain.com Web.config

<authentication mode="Forms" >
  <forms timeout="2"  name=".COMMONAUTH" domain="mydomain.com"/>
</authentication>

在一分钟后刷新system.mydomain.com中的页面时,所有页面都保持不变,我仍然经过身份验证。不确定将第3个应用程序引入此设置时会发生什么

结论

我认为我的问题是因为没有在web.config中设置域,所以system.mydomain.com正在尝试刷新cookie但是正在使用自己的域,因为我没有告诉它应该在哪里做

我的问题是这些应用程序将具有不同的域绑定,并且它们将为多个客户端托管一次。我无法设置FormsAuthentication.CookieDomain,因为它是只读的。

我应该使用选项2,并让我的cookie发行者从其他应用程序中获得更低的超时时间吗?这有什么影响吗?

2 个答案:

答案 0 :(得分:1)

根据您提供的信息,您还可以选择在Application_Start中动态修改配置,以便为域属性设置正确的值(如果尚未设置):

见:

http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k%28System.Configuration.ConfigurationManager%29;k%28TargetFrameworkMoniker-.NETFramework

希望这会有所帮助


我想可以在表单元素的超时属性描述中找到提示:

http://msdn.microsoft.com/en-us/library/1d3t3c61%28v=vs.80%29.aspx

  

防止性能受损,并避免多个浏览器   对于已启用cookie警告的用户的警告,cookie为   超过指定时间的一半时间后更新。这个   可能会导致精度下降。默认值为“30”(30分钟)。

是否在system.mydomain.com上设置为2880分钟?或者它是默认的30分钟值?如果是这样,你应该在15分钟后看到一个cookie更改。


如果您像这样设置web.config,问题是否仍然存在?

<authentication mode="Forms" >
  <forms timeout="2880" name=".COMMONAUTH" domain=".mydomain.com" />      
</authentication>

答案 1 :(得分:1)

我最终做到了这一点,我不会将此标记为答案,但是如果有人指出它有任何问题的话。

在Global.asax

void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        if (Context.User == null || !Request.IsAuthenticated)
        {
            HttpContext.Current.Response.Redirect(GetLoginUrl());
        }
        else if (Context.User.Identity is FormsIdentity)
        {
            HttpCookie cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (cookie != null)
            {
                FormsAuthenticationTicket currentTicket = FormsAuthentication.Decrypt(cookie.Value);


                if (currentTicket == null && currentTicket.Expired)
                {
                    return;
                }
                FormsAuthenticationTicket newTicket = currentTicket;
                if (FormsAuthentication.SlidingExpiration)
                {
                    FormsIdentity id = (FormsIdentity)Context.User.Identity;
                    newTicket = FormsAuthentication.RenewTicketIfOld(id.Ticket);
                }

                if (currentTicket != newTicket)
                {
                    cookie.Value = FormsAuthentication.Encrypt(newTicket);
                    cookie.Expires = newTicket.Expiration;
                    cookie.Domain = WebGlobal.GetCurrentContextDomain();

                    Response.Cookies.Set(cookie);
                }
            }
        }
    }