2013-10-22 61 views
3

我們有一個需要登錄的內部ASP.NET MVC應用程序。登錄工作很好,並做到了預期的。我們有5分鐘的會話過期。在那段時間坐在單頁上之後,用戶已經失去了會話。如果他們嘗試刷新當前頁面或瀏覽到另一頁面,他們將獲得登錄頁面。MVC會話過期 - 繼續在左邊

我的問題是(在reloggin之後)告訴MVCto重定向到他們的(刷新/瀏覽)嘗試,而不是總是獲得HOME控制器頁面?

回答

3

通常這應該會自動發生。當匿名用戶訪問受保護的資源時(他是匿名的,因爲他的會話過期),FormsAuthentication模塊攔截這些請求並通過追加ReturnUrl指向受保護資源的查詢字符串參數重定向到您在web.config中註冊的loginUrl

因此,如果例如您將~/Account/LogOn配置爲您的登錄網址,並且匿名用戶嘗試點擊~/Foo/Bar受保護的資源,他將被重定向到~/Account/LogOn?ReturnUrl=%2FFoo%2FBar

然後他將看到一個登錄頁面,在那裏他將輸入他的憑證並將該表格提交給Account控制器上的[HttpPost]LogOn操作。憑證將被驗證,如果有效,將生成一個新的表單身份驗證cookie,並將用戶重定向到最初請求的受保護資源。

下面是從登錄操作相應的代碼:

[HttpPost] 
public ActionResult LogOn(LogOnModel model, string returnUrl) 
{ 
    if (ModelState.IsValid) 
    { 
     if (Membership.ValidateUser(model.UserName, model.Password)) 
     { 
      FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 
      if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") 
       && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
      { 
       return Redirect(returnUrl); 
      } 
      else 
      { 
       return RedirectToAction("Index", "Home"); 
      } 
     } 
     else 
     { 
      ModelState.AddModelError("", "The user name or password provided is incorrect."); 
     } 
    } 

    // If we got this far, something failed, redisplay form 
    return View(model); 
} 

注意如何向用戶重定向至預設Home/Index或在成功認證returnUrl參數。

當然,我現在講的所有這個故事都是由Visual Studio創建的默認ASP.NET MVC模板。如果由於某種原因您修改了此模板,這可能會解釋您正在觀察的行爲。

在任何情況下,從我的答案中記住的事情是,如果您使用表單身份驗證,模塊將傳遞ReturnUrl查詢字符串參數最初請求的受保護資源到配置的登錄頁面。因此,在成功驗證後,您需要將用戶重定向到此頁面。

2

當您創建一個新的ASP.Net MVC項目時,此功能是開箱即用的。

總之,所請求的URL被作爲參數發送到由MVC框架Index行動AccountController,然後變成登錄頁面URL參數:

[AllowAnonymous] 
public ActionResult Login(string returnUrl) 
{ 
    ViewBag.ReturnUrl = returnUrl; 

    return View(); 
} 

當用戶帖子他憑據和成功的日誌中,returnUrl用於將用戶重定向到最初請求的頁面:

[HttpPost] 
[AllowAnonymous] 
public ActionResult Login(LoginModel model, string returnUrl) 
{ 
    if (ModelState.IsValid && Membership.ValidateUser(model.UserName, model.Password)) 
    { 

    return RedirectToLocal(returnUrl); 
    } 

    // If we got this far, something failed, redisplay form 
    ModelState.AddModelError("LogInIncorrectError", Resources.LogInIncorrectError); 

    return View(model); 
} 

private ActionResult RedirectToLocal(string returnUrl) 
{ 
    if (Url.IsLocalUrl(returnUrl)) 
    { 
    return Redirect(returnUrl); 
    } 

    return RedirectToAction("Index", "Home"); 
} 

我建議你創建一個新的項目,看看它是如何工作?

請注意,這隻適用於HttpGet,如果用戶提交表單,它將不起作用。

2

通常,這發生在ASP.NET MVC應用程序中的AccountController開箱即用。在默認Login動作看一看:

[AllowAnonymous] 
public ActionResult Login(string returnUrl) 
{ 
    ViewBag.ReturnUrl = returnUrl; 
    return View(); 
} 

[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); 
} 

// later... 
private ActionResult RedirectToLocal(string returnUrl) 
{ 
    if (Url.IsLocalUrl(returnUrl)) 
     return Redirect(returnUrl); 
    return RedirectToAction("Index", "Home"); 
} 

當會話過期並且用戶將被重定向到登錄頁面時,系統應該被供應returnUrl參數重定向。如果它不在您的應用程序中,那麼您的應用程序中的哪些內容與此情況下的默認設置不同?

請注意第一個Login操作(該操作僅在用戶重定向到該用戶後呈現登錄頁面)包含ViewBag中的值。此頁面的默認視圖將該值添加到form元素,以便它將包含在登錄POST請求中。第二個Login操作接收到該請求,然後將用戶指向該提供的URL(或默認爲/Index/Home,如幫助程序方法中所示)。

您的應用程序是否維護這一系列事件?如果不是的話,這一連串事件是如何破裂的?按照慣例,您應該是:

  1. 從會話到期重定向中接收returnUrl
  2. 在登錄表單中包含returnUrl
  3. 成功登錄後將用戶重定向到returnUrl