ReturnUrl Points to an ActionResult

Here is how the scenario goes:

  • Start an MVC project from scratch
  • Test Controller decorated with [Authorize] attribute
  • User Logs in and directed to Home
  • User clicks a link that redirects to the TestController 's Index method
  • User waits 60 seconds for the Forms Authentication to timeout
  • User clicks a link that calls an ActionMethod residing on the TestController
  • The MVC framework redirects user to Login page and attaches the ActionMethod name to the URL instead of attaching the Index Action Method
  • TestController :

    [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 :

  • When a user clicks the link after timeout, no Test Actions are hit before the redirection to the Login page takes place
  • All routes are the default as provided when starting an Empty MVC project from scratch in VS2017

  • 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.

    链接地址: http://www.djcxy.com/p/57860.html

    上一篇: 用flex文件编译错误

    下一篇: ReturnUrl指向一个ActionResult