Как исправить проблему с перенаправлением пользователя на страницу входа после успешного входа, но не на страницу пользователя?
В MVC4 я создал пользовательский поставщик членства, который возвращает true, если проходит аутентификация пользователя. Здесь нет ничего важного - эта часть работает так, как должна:
public override bool ValidateUser(string username, string password)
{
var crypto = new SimpleCrypto.PBKDF2(); // type of encryption
// TODO: using (var unitOfWork = new Website.Repository.UnitOfWork(_dbContext))
//var unitOfWork1 = new Website.Repository.UnitOfWork(_dbContext);
using (var db = new Website.DAL.WebsiteDbContext())
{
var user = db.Users
.Include("MembershipType")
.FirstOrDefault(u => u.UserName == username);
if (user != null && user.Password == crypto.Compute(password, user.PasswordSalt))
{
FormsAuthentication.SetAuthCookie(username, true);
return true;
}
}
return false;
}
В моем действии входа в систему:
[HttpPost]
[AllowAnonymous]
public ActionResult Login(Models.UserModel user)
{
if (ModelState.IsValid)
{
// custom membership provider
if (Membership.ValidateUser(user.UserName, user.Password))
{
// Cannot use this block as user needs to login twice
//if (User.IsInRole("WaitConfirmation")) // checks the custom role provider and caches based on web.config settings
//{
// //TempData["EmailAddress"] = thisUser.Email;
// // email address has not yet been confirmed
// return RedirectToAction("WaitConfirmation");
// //return View("Account", thisUser)
//}
//else
//{
// // get custom identity - user properties
// string userName = UserContext.Identity.Name;
// //CustomIdentity identity = (CustomIdentity)User.Identity;
// var identity = UserContext.Identity;
// int userId = identity.UserId;
// return RedirectToAction("Index", "Dashboard");
//}
if (User.Identity.IsAuthenticated && User.IsInRole("WaitConfirmation")) // checks the custom role provider and caches based on web.config settings
{
return RedirectToAction("WaitConfirmation");
}
else if (User.Identity.IsAuthenticated)
{
// get custom identity - user properties
string userName = UserContext.Identity.Name;
return RedirectToAction("Index", "Dashboard");
}
}
else
{
ModelState.AddModelError("", "Login data is incorrect.");
}
}
return View(user);
}
При переходе по коду, когда пользователь впервые входит в систему, User.Identity.IsAuthenticated
ложь, и страница перенаправляется обратно на страницу входа. На данный момент, если я либо:
- вручную перейти на страницу пользователя (Dashboard), пользователю доступны подробности
- войдите снова, это работает
Я считаю, что ответ лежит где-то в том, почему User.Identity.IsAuthenticated
не сразу true
но не могу понять, что это неверно в первый раз.
Первый блок закомментированного кода завершается с Unable to cast object of type 'System.Security.Principal.GenericIdentity' to type 'Website.AdminWebsite.Infrastructure.CustomIdentity'
как нет IsAuthenticated
проверять.
Предложения?
2 ответа
Прочитав статью @mcsilvio's, я добавил RedirectToAction()
следующим образом начать новый жизненный цикл страницы:
public ActionResult Login(Models.UserModel user)
{
if (ModelState.IsValid)
{
// custom membership provider
if (Membership.ValidateUser(user.UserName, user.Password))
{
return RedirectToAction("VerifyIdentity", user);
}
else
{
ModelState.AddModelError("", "Login data is incorrect.");
}
}
return View(user);
}
public ActionResult VerifyIdentity(Models.UserModel user)
{
if (User.Identity.IsAuthenticated && User.IsInRole("WaitConfirmation")) // checks the custom role provider and caches based on web.config settings
{
return RedirectToAction("WaitConfirmation");
}
else if (User.Identity.IsAuthenticated)
{
// get custom identity - user properties
string userName = UserContext.Identity.Name;
return RedirectToAction("Index", "Dashboard");
}
return View(User);
}
Это сработало, но мне интересно, есть ли лучший способ или это всегда делается так?
Этот пост описывает проблему с похожими симптомами.
http://forums.asp.net/t/1177741.aspx
Пожалуйста, прочтите и убедитесь порядок ваших событий (например, Authenticate, LoggedIn)