Here is a use case of my login using a CustomMembershipProvider
- User Logs in MembershipProvider validates user account
- User property of Membership is set to user details coming from the database
- An authentication ticket is created
- Forms authentication cookie is added.
- User is logged in
Here is a use case of my problem
- Stop whe web development server
- Start the web development server, and user is still logged in (due to cookie?)
- User property Membership is set to null due to server restart/failure
- Application throws exception due to null user value
The only solution I could think off is to clear all cookies on Application_Start() but I don't know how is that even possible as Request is out of context during application start.
Do you have any ideas how to solve this kind of problem?
Here is the code:
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);
开发者_JS百科 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;
}
}
Here is the login method of the 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("/");
}
Suggestions below are not doable because whenever I restart the server here is the case.
- Request.IsAuthenticated is FALSE on Application_BeginRequest;
- Request.IsAuthenticated is TRUE on my 'View'
why is this happening?
You should perform step 2 on each request or store the user details into the UserData part of the authentication cookie.
In the Application_AuthenticateRequest check if Request.IsAuthenticated=true but User object is null then re-populate it.
精彩评论