使用自定义表单身份验证时的表单身份验证续订问题

7

我的项目由于Forms Auth Cookies的冲突而无法更新Forms Authentication Session。

详细描述:

用户登录后,会创建一个forms auth cookie(FACookieA),并进行身份验证。然而,在更新cookie时,会创建第二个forms auth cookie(FACookieB),并且不会更新FACookieA。在FACookieA到期时间之后请求页面时,用户将被重定向到登录页面,即使在FACookieB到期时间之前也是如此。

生成的cookies:

请注意,两个cookie具有相同的名称。

FACookieA

name: FormsAuth
domain: .formsauth.com

请注意在.NET前添加的".","formsauth.com"来自Forms身份验证票证部分。
FACookieB:
name: FormsAuth
host: a.formsauth.com

请注意Cookie使用"host"而不是"domain","a.formsauth.com"基于当前请求的URL域。 已测试的项目URL:
a.formsauth.com

Web.config:

<forms loginUrl="~/Account/Login.aspx" name="FormsAuth"/>

代码

public partial class Account_Login : System.Web.UI.Page
{   
    protected void LoginButton_Click(object sender, EventArgs e)
    {
        if (Membership.ValidateUser(LoginUser.UserName.Trim(), LoginUser.Password.Trim()))
        {
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                 1,
                "username",
              DateTime.Now,
              DateTime.Now.AddMinutes(2),
              false,
              string.Empty
              );

            string encryptedTicket = FormsAuthentication.Encrypt(ticket);
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            cookie.Domain = "formsauth.com";
            cookie.Path = FormsAuthentication.FormsCookiePath;
            Response.Cookies.Remove(cookie.Name);
            Response.Cookies.Add(cookie);
            Response.Redirect("~/Account/ChangePassword.aspx"); //authenticated area

        }else
        {
            Response.Write("Invalid UserID and Password");
        }
    }
}

问题:

1) 如何生成一个表单认证cookie,使用户可以更新表单认证会话而不会被注销?

注意事项:

1) 项目需要支持多种语言,可能的域格式如下:

a.formsauth.com
a.en.formsauth.com
a.us.formsauth.com

并且。
b.formsauth.com
b.en.formsauth.com
b.us.formsauth.com

因此,我无法在表单元素中声明性地设置域属性。因为两组域名不能共享cookie,只允许在一组域名内共享cookie。也就是说,同一代码库可用于具有不同域名的不同应用程序。但是一组域名可以共享cookie。
2)默认内置的FormsAuthenticationModule会更新用户会话cookie,这就是为什么我无法控制cookie中的域的原因。请注意,如上所示,FormsAuthenticationTicket用于创建cookie以供用户登录使用。
你有什么想法吗?

当您刷新Cookie时,是否设置了cookie.Domain = "formsauth.com"; - Khanh TO
我不太记得 ASP.NET Forms Auth,所以这可能完全不适用于您的实现,但您是否尝试将 slidingExpiration="true" cookieless="UseCookies" timeout="x" 添加到 web.config 中的 <forms> 中?x 是用户在不活动一段时间后需要再次登录的分钟数。 - JW Lim
1
此外,您可能需要更改Web.config文件如下: <forms loginUrl="~/Account/Login.aspx" name="FormsAuth" domain="formsauth.com"/> 这是为了确保默认的FormsAuthenticationModule将生成具有相同域而不是空域的cookie。例如,FormsAuthenticationModule生成过期的cookie并将其推送到浏览器。如果未设置域(null),则将域的选择留给浏览器。这可能会带来麻烦 - anikiforov
@anikiforov 对于混淆感到抱歉,我已更新考虑部分,请查看。 - Pingpong
在查看您的更新后,我建议尝试以下步骤: 1)在IIS中创建一个网站,并在其中添加两个Web应用程序:A和B。 应用程序A将提供a.formsauth.com及其子域名,应用程序B将提供b.formsauth.com及其子域名。 2)在web.config中的<forms>元素中设置domain="formsauth.com"。 3)分别设置cookiePath为/A和/B,这将使您的Cookie仅适用于各自的应用程序(您也可以使用<forms>元素进行此操作)。 您将部署两个类似的Web应用程序实例,但配置将不同。 - anikiforov
显示剩余11条评论
3个回答

0

代码的逻辑不是很清晰,不清楚你为什么试图替换 cookie。

但我猜测重定向发生在新 cookie 注册之前。

        Response.Cookies.Remove(cookie.Name);

请在此处添加代码以检查在尝试添加其他内容之前是否已删除 cookie。
        Response.Cookies.Add(cookie);

在重定向之前,添加代码以确保浏览器已经注册了 cookie。

你好,能否请您详细说明一下,并提供代码示例? - Pingpong

0
尝试使用以下代码。我希望这能帮到你。
如果(Membership.ValidateUser(LoginUser.UserName.Trim(),LoginUser.Password.Trim())) {
                int timeout = model.RememberMe ? 525600 : 30;
                //DateTime timeout = model.RememberMe ? 525600 : 30;
                 string userData = JsonConvert.SerializeObject(model);
                 FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, login[0].adminUserName, DateTime.Now, DateTime.Now.AddMinutes(525600), false, userData);

                string enTicket = FormsAuthentication.Encrypt(authTicket);
                HttpCookie authcookie = new HttpCookie(FormsAuthentication.FormsCookieName, enTicket);
                Response.Cookies.Add(authcookie);



            return  Response.Redirect("~/Account/ChangePassword.aspx"); //authenticated area


            }
            else
            {
                Response.Write("Invalid UserID and Password");
            }

0

您不能混合使用具有相同名称的主机和域名Cookie。为使其正常工作,所有Cookie都需要在顶级域名下设置。


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