为什么此自定义标识用户上下文不会在MVC中保留?

时间:2015-09-03 15:34:16

标签: c# asp.net-mvc custom-membershipprovider

我创建了CustomPrincipal,CustomIdentity,CustomMembershipProvider等,并在用户登录时全部填充:

    public class CustomIdentity : IIdentity
    {

        private IIdentity _identity;

        // in the future maybe use a dictionary instead
        //private Dictionary<string, object> _customValues

        private int _userId;
        private bool _IsAuthenticated;
        private string _name;
        private string _displayName;
        private string _role;


        private Website _currentProject;

        public Website CurrentProject
        {
            get { return _currentProject; }
            set { _currentProject = value; }
        }


        private string _userName;

        public string UserName
        {
            get { return _userName; }
            set { _userName = value; }
        }
   ...

所有这些都有效,我可以在UserContext.Identity中看到值。

但是,当我尝试设置UserContext.Identity.CurrentProject = website;并稍后再查看(页面重新加载)时,CurrentProject对象为空。

我正在尝试使用自定义UserContext来保留特定于用户的值,而不是使用会话对象/变量。

为什么这不保留价值的任何想法?

- 更新 -

自从我查看这个项目已经有一段时间了,在Global.asax我发现了以下内容:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{

    //var user = HttpContext.Current.User;    // as IPrincipal
    //if (user.Identity.IsAuthenticated)
    //{
    //    // same thing as below
    //}

    //if (Request.IsAuthenticated)
    //{
    //    //get the username which we previously set in
    //    //forms authentication ticket in our login1_authenticate event
    //    string username = HttpContext.Current.User.Identity.Name;

    //    // Retrieves the cookie that contains your custom FormsAuthenticationTicket.
    //    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

    //    // Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
    //    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

    //    var fromsIdentity = new FormsIdentity(authTicket);

    //    //build a custom identity and custom principal object based on this username
    //    var identity = new CustomIdentity(authTicket);
    //    var principal = new CustomPrincipal(identity);

    //    //set the principal to the current context
    //    HttpContext.Current.User = principal;
    //}

    if (Request.IsAuthenticated) 
    {

        // Retrieves the cookie that contains your custom FormsAuthenticationTicket.
       // HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        // Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
        //FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

       // var fromsIdentity = new FormsIdentity(authTicket);

        //build a custom identity and custom principal object based on this username
        //var identity = new CustomIdentity(authTicket);
        //var principal = new CustomPrincipal(identity);

        // TODO: Add checks so we only do the following once per login.

        // Get the GenericPrincipal identity  
        IIdentity ui = HttpContext.Current.User.Identity;  

        /* Extract Name, isAuthenticated, AuthenticationType from
            the identity of the GenericPrincipal and add them including 
            any custom properties to the custom identity. I added a 
            few extra properties to my custom identity. */

        //CustomIdentity customIdentity = new CustomIdentity(ui.Name);

        CustomPrincipal customPrincipal = new CustomPrincipal(ui.Name);

        // Set custom principal 
        HttpContext.Current.User = customPrincipal;

    }

其中一些是在正确的轨道上 - 其中大部分已被注释掉。

2 个答案:

答案 0 :(得分:1)

您必须在每篇回发中替换用户,例如:http://www.codeproject.com/Tips/574576/How-to-implement-a-custom-IPrincipal-in-ASP-NET-MV

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
      HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
      if (authCookie != null)
      {
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        if (authTicket.UserData == "OAuth") return;
        CustomPrincipalSerializedModel serializeModel = 
          serializer.Deserialize<CustomPrincipalSerializedModel>(authTicket.UserData);
        CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
        newUser.Id = serializeModel.Id;
        newUser.FirstName = serializeModel.FirstName;
        newUser.LastName = serializeModel.LastName;
        HttpContext.Current.User = newUser;
      } 
}

这会在每次回发时运行,因此您必须每次都重建自定义标识。为方便起见,您可以将对象保留在会话中,而不是从故障单或数据库重新加载。

答案 1 :(得分:0)

您必须在客户端浏览器上设置cookie。在Cookie中,您将放置一些内容(可能是用户ID),您可以从中再次填充customIdentity。现在在Global.asax中,对于AuthenticationRequest事件,您将检查cookie是否存在,如果是,您将必须通过解密cookie的值从cookie中取出(先前存储的Id)某些内容并填充您的customIdentity并将其添加到当前线程上下文。

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
   HttpContext.Current.User = new GenericPrincipal(customIdentity, null);
}