IsAuthenticated 是假的!奇怪的行为复习问题
这是登录函数(在验证用户名和密码后,我将用户数据加载到“user”变量中并调用登录函数:
public static void Login(IUser user)
{
HttpResponse Response = HttpContext.Current.Response;
HttpRequest Request = HttpContext.Current.Request;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
user.UserId.ToString(), DateTime.Now, DateTime.Now.AddHours(12), false,
UserResolver.Serialize(user));
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(ticket));
cookie.Path = FormsAuthentication.FormsCookiePath;
Response.Cookies.Add(cookie);
string redirectUrl = user.HomePage;
Response.Redirect(redirectUrl, true);
}
UserResolver 是以下类:
public class UserResolver
{
public static IUser Current
{
get
{
IUser user = null;
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
user = Desrialize(ticket.UserData);
}
return user;
}
}
public static string Serialize(IUser user)
{
StringBuilder data = new StringBuilder();
StringWriter w = new StringWriter(data);
string type = user.GetType().ToString();
//w.Write(type.Length);
w.WriteLine(user.GetType().ToString());
StringBuilder userData = new StringBuilder();
XmlSerializer serializer = new XmlSerializer(user.GetType());
serializer.Serialize(new StringWriter(userData), user);
w.Write(userData.ToString());
w.Close();
return data.ToString();
}
public static IUser Desrialize(string data)
{
StringReader r = new StringReader(data);
string typeStr = r.ReadLine();
Type type=Type.GetType(typeStr);
string userData = r.ReadToEnd();
XmlSerializer serializer = new XmlSerializer(type);
return (IUser)serializer.Deserialize(new StringReader(userData));
}
}
并且 global.asax 实现以下内容:
void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
IPrincipal p = HttpContext.Current.User;
if (p.Identity.IsAuthenticated)
{
IUser user = UserResolver.Current;
Role[] roles = user.GetUserRoles();
HttpContext.Current.User = Thread.CurrentPrincipal =
new GenericPrincipal(p.Identity, Role.ToString(roles));
}
}
第一个问题: 我做对了吗?
第二个问题——奇怪的事情! 我传递给 Login 的用户变量有 4 个成员:UserName、Password、Name、Id。 当 UserResolver.Current 执行时,我得到了用户实例。 我决定更改用户结构 - 添加一个 Warehouse 对象数组。 从那时起,当 UserResolver.Current 执行时(登录后),HttpContext.Current.User.Identity.IsAuthenticated 为 false,我无法获取用户数据。 当我从用户结构中删除 Warehouse[] 时,它再次开始正常,并且 HttpContext.Current.User.Identity.IsAuthenticated 在我登录后变为 true。
这种奇怪行为的原因是什么?
This is the login function (after I validate user name and password, I load user data into "user" variable and call Login function:
public static void Login(IUser user)
{
HttpResponse Response = HttpContext.Current.Response;
HttpRequest Request = HttpContext.Current.Request;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
user.UserId.ToString(), DateTime.Now, DateTime.Now.AddHours(12), false,
UserResolver.Serialize(user));
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(ticket));
cookie.Path = FormsAuthentication.FormsCookiePath;
Response.Cookies.Add(cookie);
string redirectUrl = user.HomePage;
Response.Redirect(redirectUrl, true);
}
UserResolver is the following class:
public class UserResolver
{
public static IUser Current
{
get
{
IUser user = null;
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
user = Desrialize(ticket.UserData);
}
return user;
}
}
public static string Serialize(IUser user)
{
StringBuilder data = new StringBuilder();
StringWriter w = new StringWriter(data);
string type = user.GetType().ToString();
//w.Write(type.Length);
w.WriteLine(user.GetType().ToString());
StringBuilder userData = new StringBuilder();
XmlSerializer serializer = new XmlSerializer(user.GetType());
serializer.Serialize(new StringWriter(userData), user);
w.Write(userData.ToString());
w.Close();
return data.ToString();
}
public static IUser Desrialize(string data)
{
StringReader r = new StringReader(data);
string typeStr = r.ReadLine();
Type type=Type.GetType(typeStr);
string userData = r.ReadToEnd();
XmlSerializer serializer = new XmlSerializer(type);
return (IUser)serializer.Deserialize(new StringReader(userData));
}
}
And the global.asax implements the following:
void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
IPrincipal p = HttpContext.Current.User;
if (p.Identity.IsAuthenticated)
{
IUser user = UserResolver.Current;
Role[] roles = user.GetUserRoles();
HttpContext.Current.User = Thread.CurrentPrincipal =
new GenericPrincipal(p.Identity, Role.ToString(roles));
}
}
First question:
Am I do it right?
Second question - weird thing!
The user variable I pass to Login has 4 members: UserName, Password, Name, Id.
When UserResolver.Current executed, I got the user instance.
I descided to change the user structure - I add an array of Warehouse object.
Since that time, when UserResolver.Current executed (after Login), HttpContext.Current.User.Identity.IsAuthenticated was false and I couldn't get the user data.
When I removed the Warehouse[] from user structure, it starts to be ok again and HttpContext.Current.User.Identity.IsAuthenticated become true after I Login.
What is the reason to this weird behaviour?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您不需要从 Global.asax 执行
HttpContext.Current
。 Global.asax 派生自HttpApplication
。因此,您需要做的就是获取Context
属性。这可能有助于使代码更清晰一些。根据您的错误,问题似乎是您的序列化函数或反序列化函数损坏了数据。然而,问题可能不在于这些功能。要么是序列化 Warehouse 对象时出现问题(序列化复杂类型有时可能很棘手),要么是实际数组的序列化出现问题。由于您使用的是默认的 .NET
XmlSerializer
,因此有一篇关于自定义和控制不同对象处理方式的好文章,位于 http://www.diranieh.com/NETSerialization/XMLSerialization.htm 。另一方面,您确定这是在应用程序中存储这些数据的最佳方式吗?存储用户 ID 和名称是有意义的。当您开始在 cookie 中存储复杂对象的序列化数组时,这可能表明您一开始就没有正确解决问题。
First, you don't need to do an
HttpContext.Current
from Global.asax. Global.asax derives fromHttpApplication
. So all you need to do is to get theContext
property. This might help make that code a little cleaner.Based on your error, it seems like the issue is that either your serializing function or your deserializing function corrupts the data. However, the problem area is probably not those functions. Either there is an issue in serializing the Warehouse object (serializing complex types can sometimes be tricky), or in the serialization of the actual array. Since you are using the default .NET
XmlSerializer
, There is a good article on customizing and controlling the way different objects are handled available at http://www.diranieh.com/NETSerialization/XMLSerialization.htm .On another note, are you sure that this is the best way for you to store this data in your application? Storing a user-id and name makes sense. When you start storing serialized arrays of complex objects in your cookie, it might indicate you are not approaching the problem correctly to begin with.
我猜测您的代码位于某处的登录事件中,并且您正在构建自定义表单身份验证。
然后,您还需要在每个页面请求上从 cookie 构建 User 对象
编辑
尝试将其添加到您的全局
I am guessing that your code is in a log on event somewhere and your building a custom forms auth.
You also need to then build the User object from the cookie on every page request
EDIT
Try adding this to your global