Here is how the scenario goes:
TestController
's Index
methodTestController
Index
Action MethodTestController:
[Authorize]
public class TestController : Controller
{
// GET: Test
public ViewResult Index()
{
return View();
}
[ValidateInput(false)]
public ActionResult ActionTest()
{
return new EmptyResult();
}
}
HomeController:
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
AccountController:
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
try
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
return RedirectToAction(controllerName: "Home", actionName: "Index");
}
catch
{
return View(model);
}
}
return View(model);
}
}
Login.chtml
@model TestLoginProject.Models.LoginViewModel
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
.....................
</head>
<body>
<div class="container">
@using (@Html.BeginForm("Login", "Account", new { returnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { @class = "form-signin" }))
{
@Html.AntiForgeryToken()
....................
....................
}
</div>
</body>
</html>
Web Config
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="1" />
</authentication>
The expectation of the return url is:
http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fIndex
Instead, the current value is:
http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fActionTest
Notes:
This is a normal behavior that you mentioned!
The MVC framework redirects user to Login page and attaches the ActionMethod name to the URL instead of attaching the
Index
Action Method
Many thanks to MVC Security pipeline. When you use forms authentication and the user is not authenticated or authorized, the ASP.NET security pipeline redirects to the login page and passes returnUrl
as a parameter equal to the page that redirected to the login page (here is the controller action which requires authorization which you called by clicking on a link).
So here you can't expect index (currently loaded page with no valid and persistent authentication) and subsequently the ActionMethod
calls security pipeline and the returnurl
is enumerated just in time.
Note that this is because of Synchronized communication between Controller and View.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With