为什么在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 -相同的问题
在进一步的混乱中,我将代码从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
中??