2013-11-21 44 views
33

我正在研究'ASP.NET MVC 4'應用程序。我正在使用/學習SimpleMembershipProvider,並嘗試使用VS2012創建的默認邏輯與Internet template(如果我沒有弄錯,那是開箱即用的'SimpleMembershipProvider')。我該如何在MVC中使用ReturnUrl = ViewBag.ReturnUrl 4

我被困在AccountController,我實在不明白把我究竟如何可以使用這個方法:

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

從我瞭解的整體思路是,以獲取要從其重定向到的位置你已經決定登錄(正是我想要完成的)。我看了看它是如何在視圖中使用:

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) 

查找這裏居然ViewBag.ReturnUrl設置有一定的價值,我只得到了這種方法在這裏的地方:

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

和我對我應該如何獲取位置/網址感到困惑。我設置了一些斷點,我從來沒有看到returnUrlnull不同,在這種情況下,它似乎對我來說非常合乎邏輯,因爲它不會在任何地方獲得價值(除非我錯過某些課程)。

所以我真的無法弄清楚這是如何工作的。我張貼上面的內容只是爲了表明我試圖做我的功課,我儘可能多地進行調查,但是我沒有找到答案,所以我在這裏問。你能提供解釋/例子說明這個實際工作嗎?

回答

50

使用表單身份驗證時,用戶未通過身份驗證或授權的ASP。NET安全管道將重定向到登錄頁面並作爲查詢字符串中的參數傳遞returnUrl等於重定向到登錄頁面的頁面。登錄操作獲取此參數的值並將其放入ViewBag中,以便將其傳遞給View。

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

該視圖然後將此值存儲在視圖中此代碼行所示的窗體中。

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) 

它存儲在視野中的原因是,當用戶執行輸入自己的用戶名和密碼,即處理後回將有機會獲得這個值時,控制器動作後提交。

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

如果模型狀態是有效的,它們是通過調用WebSecurity.Login方法,然後驗證它調用方法RedirectToLocal與這些來自查看RETURNURL的值,它最初來自形成創建該視圖的登錄操作。

returnUrl如果用戶沒有被重定向到登錄頁面,那麼值將爲空,就像他們在默認佈局中單擊頁面頂部的登錄鏈接時一樣。在這種情況下,成功登錄後用戶將被重定向到主頁。 returnUrl的全部用途是自動將用戶發送回他們在驗證/授權之前嘗試訪問的頁面。

+0

那麼,我有這個問題 - 'returnUrl'是否足夠可靠以基於條件檢查。我想要的是如果重定向來自'AdminController',在這種情況下是'returnUrl =/admin'字符串,則實現特定的邏輯。儘管我想我已經開始理解事情是如何工作的,但我仍然懷疑這個變量是否足夠安全或者它可以很容易地改變? – Leron

+0

它不安全,因爲它在查詢字符串中,所以可以很容易地進行更改。任何人都可以在他們的Web瀏覽器中更改此值。 –

+0

這不適合我。但是,您始終可以這樣做: HttpContext.Request.Params [「ReturnUrl」]; – Tomer

3

當未經身份驗證的用戶試圖進入需要身份驗證的應用程序部分時,則會出現returnUrl。未經身份驗證的用戶請求的Url基本上存儲在returnUrl中。

你可以通過PluralSight tutorial: Building Applications with ASP.NET MVC 4

+1

感謝您分享視頻。現在我需要一個快速解決方案,首先我認爲模板只生成一個腳手架,我需要用這樣的東西來改變它 - 'new {ReturnUrl = ViewContext.HttpContext.Request.UrlReferrer.PathAndQuery})'但是在你的文章我做了一些更多的測試,似乎所有東西都是內置的。我認爲答案在[Authorize]屬性中,它是實現的,但是從理解良好的人那裏得到解釋會很好。 – Leron

10

這是因爲默認的ASP.NET MVC模板使用Forms authentication和控制器與[Authorize]屬性來修飾:

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

[Authorize] 
public class AccountController : Controller 
{ 
    //... 
} 

這意味着,如果用戶不驗證它將被重定向到forms元素的LoginUrl屬性中定義的登錄頁面。

在重定向過程中,FormsAuthentication這是一個HttpModule將自動附加查詢字符串中請求的url。

所以,如果你導航到/Account/Login,你不會在查詢字符串中得到任何東西,因爲它用[AllowAnonymous]屬性裝飾。 但是,如果你瀏覽到/Account/Manage你會發現,在查詢字符串的RETURNURL變得/Account/Manage(/Account/Login?ReturnUrl=%2fAccount%2fManage)

這樣你就不會設置RETURNURL,框架會爲你,你只需要使用它在AccountController知道在哪裏在認證之後重定向用戶。