IsAuthenticated是假的!怪异的行为+评价问题 [英] IsAuthenticated is false! weird behaviour + review question

查看:151
本文介绍了IsAuthenticated是假的!怪异的行为+评价问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是登录功能(后我验证用户名和密码,我的用户数据加载到用户的变量,并调用登录功能:

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是下面的类:

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));
    }
}

和在Global.asax实现了以下内容:

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?

第二个问题 - 奇怪的事情!
用户变量我传递给登录有4名成员:用户名,密码,姓名,身份证。
当UserResolver.Current执行,我得到了用户实例。
我descided改变用户结构 - 我想补充仓库对象的数组。
自那时起,当UserResolver.Current执行(登录后),HttpContext.Current.User.Identity.IsAuthenticated是假的,我不能得到用户的数据。
当我删除了仓库[]从用户结构,它开始再次确定,我登录后HttpContext.Current.User.Identity.IsAuthenticated成真。

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?

推荐答案

首先,你并不需要从Global.asax中做了一个 HttpContext.Current 。从Global.asax中的HttpApplication 派生的。因此,所有你需要做的是让上下文属性。这可能有助于使该code干净了一点。

First, you don't need to do an HttpContext.Current from Global.asax. Global.asax derives from HttpApplication. So all you need to do is to get the Context property. This might help make that code a little cleaner.

    //this is all you need in your global.asax
    void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        if(Context.User.Identity.IsAuthenticated)
        {
            var user = UserResolver.Current;
            Context.User = Thread.CurrentPrincipal = new UserWrapperPrincipal(user, Context.User.Identity);
        }
    }

    //this helper class separates the complexity
    public class UserWrapperPrincipal: IPrincipal, IUser
    {
        private readonly IUser _user;
        private readonly IIdentity _identity;

        public UserWrapperPrincipal(IUser user, IIdentity identity)
        {
            _user = user;
            _identity = identity;
        }

        private IList<string> RoleNames
        {
            get { return _user.GetUserRoles().Select(role => role.ToString()); }
        }

        public IIdentity Identity { get { return _identity; } }

        public bool IsInRole(string role) { return RoleNames.Contains(role); }

    }

根据你的错误,好像问题是,要么你的序列化功能或反序列化功能破坏的数据。然而,问题区域可能不是这些功能。要么没有在序列化对象仓库(序列化复杂类型有时会非常棘手)问题,还是在实际阵列的序列化。由于您使用的是默认.NET 的XmlSerializer ,对定制和控制不同对象的处理提供的 http://www.diranieh.com/NETSerialization/XMLSerialization.htm

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 .

另外要注意,你确定这是你在应用程序中保存这些数据的最佳方式?存储用户ID和名称是有道理的。当您启动存储复杂对象的序列化数组在你的cookie,它可能表明你没有正确地接近问题的开始。

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.

这篇关于IsAuthenticated是假的!怪异的行为+评价问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆