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

Posted

技术标签:

【中文标题】自定义表单身份验证的表单身份验证续订问题【英文标题】:Forms Authentication Renewal Issue with Custom Forms Authentication 【发布时间】:2015-07-02 05:27:45 【问题描述】:

由于表单身份验证 Cookie 冲突,我的项目在更新表单身份验证会话时遇到问题。

详细说明:

用户登录后,会创建一个表单身份验证 cookie (FACookieA),并对其进行身份验证。但是,在更新 cookie 时,会创建第二个表单身份验证 cookie (FACookieB),并且不会更新 FACookieA。用户在FACookieA的过期时间之后被重定向到页面请求的登录页面,即使它在FACookieB的过期时间之前。

生成的 cookie:

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

FACookieA

name: FormsAuth
domain: .formsauth.com

请注意“。”由 .NET 预先附加,“formsauth.com”来自 Forms Authentication Ticket 部分

FACookieB

name: FormsAuth
host: a.formsauth.com

请注意 cookie 使用的是“host”,而不是域,“a.formsauth.com”是基于当前请求的 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) 如何生成一个forms auth cookie,让用户可以更新forms auth session,不会被注销?

注意事项:

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

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

b.formsauth.com
b.en.formsauth.com
b.us.formsauth.com

因此,我无法以声明方式设置 Forms 元素的域属性。因为两组域不能共享cookie,所以允许在一组内共享cookie。也就是说,相同的代码库用于具有不同域的不同应用程序。但是一组域可以共享cookie。

2) 默认的内置 FormsAuthenticationModule 更新用户会话 cookie,这就是为什么我无法控制 cookie 中的域。请注意,FormsAuthenticationTicket 用于在使用登录时创建 cookie,如上所示。

有什么想法吗?

【问题讨论】:

请贴出刷新cookie的代码 你刷新cookie的时候设置cookie.Domain = "formsauth.com";了吗? 我不太记得 ASP.NET Forms Auth,所以这可能根本不适用于您的实现,但是您是否尝试在 web.config 中将 slidingExpiration="true" cookieless="UseCookies" timeout="x" 添加到 &lt;forms &gt; 中? x 是用户必须再次登录之前不活动的时间(以分钟为单位)。 嗨,请看我的更新。 另外,您可能希望将您的 Web.config 更改为: 这是以确保默认的 FormsAuthenticationModule 将生成具有相同域而不是空域的 cookie。例如。 FormsAuthenticationModule 生成过期的 cookie 并将其推送到浏览器。如果未设置域(空),您将把域的选择留给浏览器。 Which may be troublesome 【参考方案1】:

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

不过,我猜测重定向是在新 cookie 注册之前发生的。

        Response.Cookies.Remove(cookie.Name);

在此处添加代码以在尝试添加其他 cookie 之前检查 cookie 是否已删除

        Response.Cookies.Add(cookie);

在此处添加代码以确保在重定向之前 cookie 已被浏览器 (?) 注册

【讨论】:

您好,能否详细说明一下,以及代码示例?【参考方案2】:

您不能混合使用同名的主机和域 cookie。为完成这项工作,所有 cookie 都需要在***域中设置。

【讨论】:

【参考方案3】:

尝试使用以下代码。希望对您有所帮助。

if (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");
            

【讨论】:

以上是关于自定义表单身份验证的表单身份验证续订问题的主要内容,如果未能解决你的问题,请参考以下文章

具有自定义外部表单和弹簧安全性的 CAS 身份验证

自定义身份验证

我们如何在 Xamarin 表单中删除/自定义 Azure AD B2C 身份验证 webview 页面标题栏?

Symfony2 自定义身份验证:用户登录但未通过身份验证

如何根据请求的范围自定义 KeyCloak 身份验证流程

Wordpress 登录表单验证