I've changed the web.config file adding the following lines.
<system.web>
<authorization>
<deny users="?"/>
</authorization>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogIn"></forms>
</authentication>
</system.web>
Now, whatever page's accessed, I'm being redirected to the login page. That's great and as I enter the credentials, I'd like the user to be directed back to where they started.
public ActionResult LogIn(string token)
{
using (Model model = new Model())
if (model.Users.Any(_ => _.Token == token))
return Redirect(Request.UrlReferrer.ToString());
return View();
}
The problem I discover is that the UrlReferrer is the login page itself so I'm only redirecting to where I'm already at on the log in page, instead of where I originally started...
What am I doing wrong?
What am I doing wrong?
You are using the old ASP.NET security (which is based on physical files and folders) for MVC (which is based on controllers and actions). The proper way to secure controllers and actions is to use AuthorizeAttribute
. ASP.NET security won't work for MVC controllers because they are not file-system based (but do note it does still come in handy for physical files - you can block direct access to them and then use a controller to provide conditional access).
When you use AuthorizeAttribute
, the login URL will automatically be built with a ReturnUrl
query string parameter which is used to redirect the user back to the location they started at.
For example, in the default MVC templates, this is the Login
method which uses the returnUrl
. It also uses RedirectToLocal
to ensure someone doesn't exploit the query string parameter to hijack the user to another website.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}