为什么此自定义身份用户上下文不保留在 MVC 中?

Why is this custom identity user context not persisting in MVC?

我创建了 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 来保留用户特定的值,而不是使用会话 objects/variables。

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

--更新--

我已经有一段时间没看过这个项目了,在 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;

    }

其中一些是否正确 - 其中大部分已被注释掉。

你必须在每个 post 后面更换用户,就像这样 post: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;
      } 
}

它在每个 postback 上运行,因此您每次都必须重建自定义标识。为方便起见,您可以将对象保存在会话中,而不是从票证或数据库中重新加载。

您必须在客户端浏览器上设置 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);
}