这是我使用 CustomMembershipProvider 登录的用例
- MembershipProvider 中的用户登录验证用户帐户
- Membership 的用户属性设置为来自数据库的用户详细信息
- 已创建身份验证票证
- 添加了表单身份验证 cookie。
- 用户已登录
这是我的问题的一个用例
- 停止 web 开发服务器
- 启动 web 开发服务器,用户仍然登录(由于 cookie?)
- 由于服务器重新启动/故障,用户属性 Membership 设置为 null
- 由于 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("/");
}
下面的建议是不可行的,因为每当我重新启动服务器时都是这种情况。
- Request.IsAuthenticated 在 Application_BeginRequest 上为 FALSE;
- Request.IsAuthenticated 在我的“视图”上为 TRUE
为什么会这样?