为什么在MVC中使用FormsAuthentication CustomIdentity和更新AuthTicket Us

本文关键字:CustomIdentity 更新 AuthTicket Us FormsAuthentication MVC 为什么 | 更新日期: 2023-09-27 18:11:51

使用表单身份验证,我用序列化的CustomIdentitySerializer对象填充UserData字段。

用户登录,我已经验证Membership.ValidateUser()工作正常

然后我开始填充CustomIdentitySerializer对象并将其发送到静态UserContext类中的静态UpdateAuthenticationTicket方法以测试数据保留- Login()/User.Identity.IsAuthenticated:

// set auth ticket
UserContext.UpdateAuthenticationTicket(user.Username, serializeModel);
// get custom identity - user properties
string userName = UserContext.Identity.UserName;
// reset login attempts
Session["_LoginAttempts"] = 0;
return RedirectToAction("Index", "Dashboard");

辅助方法:

/// <summary>
/// As we will want to update the UserData portion of the cookie while the 
/// user is logged, this will be reused
/// 
/// Auth Ticket/Cookie's UserData property is the CustomIdentitySerializer object
/// </summary>
/// <param name="userName"></param>
/// <param name="userData"></param>
public static void UpdateAuthenticationTicket(string userName, CustomIdentitySerializer userData)
{
    //var authUser = GetUser(userName);
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    string userDataSerialized = serializer.Serialize(userData);
    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,
        userName,
        DateTime.Now,
        DateTime.Now.AddMinutes(30),
        false,
        userDataSerialized,
        FormsAuthentication.FormsCookiePath);
        // encrypt the ticket
        string encTicket = FormsAuthentication.Encrypt(authTicket);
        // create/set the cookie
        HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        HttpContext.Current.Response.Cookies.Add(faCookie);
    }

userData可以随着用户在站点上的时间而改变,因此无论何时需要更改数据,我们都将重用此方法。

Global.asax.cs我有:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        var fromsIdentity = new FormsIdentity(authTicket);
        // Get the GenericPrincipal identity  
        IIdentity ui = HttpContext.Current.User.Identity;  
        CustomIdentity customIdentity = new CustomIdentity(ui.Name);
        CustomPrincipal customPrincipal = new CustomPrincipal(ui.Name);
        string userData = ((FormsIdentity)(Context.User.Identity)).Ticket.UserData;
        // Set custom principal 
        HttpContext.Current.User = customPrincipal;
    }
}
/// <summary>
/// Since we set current project and other custom user fields  through the user experience,
/// these are saved in the authticket/cookie's UserData field as a CustomIdentitySerializer object type
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie != null)
        {
            // get the current cookie
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            var fromsIdentity = new FormsIdentity(authTicket);
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            CustomIdentitySerializer userData = serializer.Deserialize<CustomIdentitySerializer>(authTicket.UserData);
            CustomPrincipal customPrincipal = new CustomPrincipal(HttpContext.Current.User.Identity.Name);
            customPrincipal.CustomIdentity.FirstName = userData.FirstName;
            customPrincipal.CustomIdentity.LastName = userData.LastName;
            customPrincipal.CustomIdentity.CurrentProject = userData.CurrentProject;
            HttpContext.Current.User = customPrincipal;
        }
    }
}

我认为这可能与没有正确设置或重写主体提供程序有关。

设置cookie值后,Application_AuthenticateRequest得到命中,然后是Application_PostAuthenticateRequest。此过程执行两次,然后返回登录页面。

似乎Application_AuthenticateRequest中的代码是没有用的,因为我没有设置任何属性。

问题是,在用户实际登录后,RedirectToAction返回到http://localhost:1982/Account/Login?ReturnUrl=%2fDashboard而不是适当的页面。

在从静态UserContext类更新cookie时有任何可预见的问题吗?

关于如何清理和开始工作,请提供一些帮助?

谢谢。

——UPDATE——

查看Application_PostAuthenticateRequest中的authCookie对象,Expires被设置为{1/1/0001 12:00:00 AM}。无论如何,authTicket cookie过期是正确的——从创建时间起30分钟。所以cookie在那里

还有什么?

——UPDATE——

在查看cookie版本时,我注意到一个区别。当我在UpdateAuthenticationTicket中设置cookie时,我检查:

authTicket.Version = 

FormsAuthentication.Decrypt (HttpContext.Current.Request.Cookies [FormsAuthentication.FormsCookieName] value)。版本= 2

不知道为什么有两个版本,如果有人能解释一下吗?我尝试设置cookie与version=2 -相同的问题

为什么在MVC中使用FormsAuthentication CustomIdentity和更新AuthTicket Us

在进一步的混乱中,我将代码从Application_PostAuthenticateRequest移动到Application_AuthenticateRequest,现在一切似乎都工作得很好:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null && HttpContext.Current.User.Identity.IsAuthenticated)
    {
        if (authCookie != null)
        {
            // get the current cookie
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            var fromsIdentity = new FormsIdentity(authTicket);
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            CustomPrincipal customPrincipal = new CustomPrincipal(HttpContext.Current.User.Identity.Name);
            CustomIdentitySerializer userData = serializer.Deserialize<CustomIdentitySerializer>(authTicket.UserData);
            if (userData != null)
            {
                customPrincipal.CustomIdentity.FirstName = userData.FirstName;
                customPrincipal.CustomIdentity.LastName = userData.LastName;
                customPrincipal.CustomIdentity.CurrentProject = userData.CurrentProject;
            }
            HttpContext.Current.User = customPrincipal;
        }
    }
}

有人能解释一下为什么会这样,因为我找到的很多参考资料都表明要把这段代码放在Application_PostAuthenticateRequest中??