0

这是我使用 CustomMembershipProvider 登录的用例

  1. MembershipProvider 中的用户登录验证用户帐户
  2. Membership 的用户属性设置为来自数据库的用户详细信息
  3. 已创建身份验证票证
  4. 添加了表单身份验证 cookie。
  5. 用户已登录

这是我的问题的一个用例

  1. 停止 web 开发服务器
  2. 启动 web 开发服务器,用户仍然登录(由于 cookie?)
  3. 由于服务器重新启动/故障,用户属性 Membership 设置为 null
  4. 由于 null 用户值,应用程序引发异常

我能想到的唯一解决方案是清除 Application_Start() 上的所有 cookie,但我不知道这怎么可能,因为 Request 在应用程序启动期间脱离上下文。

您对如何解决此类问题有任何想法吗?

这是代码:

CustomMembershipProvider

public class CustomMembershipProvider : MembershipProvider
{
    #region Unimplemented MembershipProvider Methods
    //Other methods here
    #endregion

    //private IUserRepository _userRepository = new UserRepository();

    //Ninject bindings
    private IUserRepository _userRepository;

    [Inject]
    public IUserRepository UserRepository
    {
        set
        {
            _userRepository = value;
        }
    }

    private IProfileRepository _profileRepository;

    [Inject]
    public IProfileRepository ProfileRepository
    {
        set
        {
            _profileRepository = value;
        }
    }


    public User User
    {
        get;
        private set;
    }

    public Profile Profile
    {
        get;
        set;
    }


    public CustomMembershipProvider()
    {
        MvcApplication.Container.Inject(this);
    }

    public override bool ValidateUser(string username, string password)
    {
        if (string.IsNullOrEmpty(password.Trim())) return false;

        User user = _userRepository.GetUserByUsername(username);

        user.UserType = UserHelper.GetUserTypeById(user.UserTypeId);

        if (user == null) return false;

        string hash = PasswordHelper.ComputeHash(password, user.PasswordSalt);

        if (user.Password == hash)
        {
            this.User = user;

            Profile profile = _profileRepository.GetProfileByUserId(user.UserId);

            this.Profile = profile;
            return true;
        }

        return false;
    }
}

这是Account Controller的登录方法

        [HttpPost]
        public ActionResult Login(string username, string password)
        {

            if (!provider.ValidateUser(username, password))
            {
                TempData["LoginError"] = "Incorrect";
            }
            else
            {
                User user = provider.User;

                if (!user.Verified)
                {
                    TempData["LoginError"] = "Please verify your account";
                    return Redirect(Request.UrlReferrer.LocalPath);
                }

                //FormsAuthentication.SetAuthCookie(user.Username,false);
                FormsAuthenticationTicket authTicket = new
                               FormsAuthenticationTicket(1, //version
                               username,                    //user name
                               DateTime.Now,                //creation
                               DateTime.Now.AddMinutes(30), //Expiration
                               false,                       //Persistent
                               username);                   //since Classic logins don't have a "Friendly Name"

                string encTicket = FormsAuthentication.Encrypt(authTicket);
                Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

                WebsiteObjects.Profile profile = provider.Profile;


                TempData["LoginError"] = String.Empty;
            }


        return Redirect("/");

    }

下面的建议是不可行的,因为每当我重新启动服务器时都是这种情况。

  1. Request.IsAuthenticated 在 Application_BeginRequest 上为 FALSE;
  2. Request.IsAuthenticated 在我的“视图”上为 TRUE

为什么会这样?

4

2 回答 2

1

您应该对每个请求执行第 2 步,或将用户详细信息存储到身份验证 cookie 的 UserData 部分。

于 2011-01-05T09:04:09.697 回答
0

在 Application_AuthenticateRequest 检查 Request.IsAuthenticated=true 但 User 对象是否为 null 然后重新填充它。

于 2011-01-12T15:14:08.477 回答