ReturnUrl指向ActionResult

时间:2017-10-24 19:12:32

标签: asp.net-mvc security authentication asp.net-mvc-routing forms-authentication

以下是该方案的用途:

  • 从头开始一个MVC项目
  • 使用[授权]属性
  • 修饰的测试控制器
  • 用户登录并定向到主页
  • 用户点击重定向到TestController Index方法的链接
  • 用户等待60秒以使表单身份验证超时
  • 用户点击一个链接,该链接调用驻留在TestController
  • 上的 ActionMethod
  • MVC框架将用户重定向到“登录”页面,并将 ActionMethod 名称附加到URL,而不是附加Index操作方法

的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>

网络配置

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="1" />
</authentication>

返回网址的期望为

  

http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fIndex

相反,当前值为

  

http://localhost:2441/Account/Login?ReturnUrl=%2fTest%2fActionTest

备注

  • 当用户在超时后点击链接时,在重定向到登录页面之前没有点击任何测试操作
  • 所有路由都是在VS2017中从头开始启动Empty MVC项目时提供的默认路由

1 个答案:

答案 0 :(得分:3)

这是您提到的正常行为!

  

MVC框架将用户重定向到Login页面并附加    ActionMethod 指向网址的名称,而不是附加Index操作方法

非常感谢MVC Security管道。当您使用表单身份验证且用户未经过身份验证或授权时,ASP.NET安全管道会重定向到登录页面并将returnUrl作为参数传递给等于该页面的页面重定向到登录页面(这是控制器操作,需要通过单击链接调用的授权)。

所以在这里你不能指望 index (当前加载的页面没有有效和持久的身份验证),随后ActionMethod调用安全管道而returnurl是及时列举。

请注意这是因为Controller和View之间的同步通信。