2013-12-17 63 views
8

我已經開始使用新的Asp.Net身份與Owin一個新的MVC 5站點。在我的具有[授權]屬性的「帳戶」控制器中,我有相當標準的操作;如何重定向到returnUrl在Asp.Net中工作MVC5

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

// POST: /User/Login 
     [HttpPost] 
     [AllowAnonymous] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
     { 
      try 
      { 
       if (ModelState.IsValid) 
       { 
        var userApi = new UserService(); 
        var apiUser = await userApi.LogIn(UserManager, model.CardNumber, model.Pin, model.RememberMe); 

        if (apiUser != null) 
        { 
         await SignInAsync(apiUser, model.RememberMe); 
         if (string.IsNullOrEmpty(returnUrl)) 
         {         
          return RedirectToAction("UserLoggedIn", "User");  
         } 
        } 
        else 
        { 
         ModelState.AddModelError("", "Invalid username or password."); 
        } 
       } 

      } 
      catch (Exception ex) 
      { 
       Trace.TraceError("Cannot login {0}", ex.ToString()); 
       Response.AppendToLog(ex.ToString()); 
       ModelState.AddModelError("", ex.ToString()); 
      } 
      // If we got this far, something failed, redisplay form 
      return View(model); 
     } 

我的問題是關於在RETURNURL行爲,上面的代碼在這個意義上的作品,如果用戶沒有登錄並調用具有屬性[授權]控制器的作用,它會發送到上面的登錄操作,然後返回到請求的控制器/操作。這是偉大的,但如何?它安全嗎?

在本文中,關於「Preventing open redirect attacks」(針對早期版本的Asp.Net MVC),建議在執行重定向之前檢查returnUrl是否是本地url,是我應該做的還是它現在由框架處理?

乾杯, 奧拉

回答

13

您需要檢查的網址是當地確實使用這種方法(它不是由框架自動處理):http://msdn.microsoft.com/en-us/library/system.web.mvc.urlhelper.islocalurl%28v=vs.118%29.aspx

if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl)) 
{ 
    return Redirect(returnUrl); 
} 
+0

你有它不處理的信息任何來源?看起來很奇怪,他們會自動將功能重定向到returnUrl,但不遵循自己的指導原則。因此原來的問題。 –

+0

爲什麼不嘗試操縱returnUrl並查看會發生什麼?順便說一句,在你的代碼中,'returnUrl'參數是從不使用的。 – Marthijn

+0

是的,我想這將是一個選項。我知道returnUrl從來沒有用在我的動作中,但網站仍然正確地重定向,這就是爲什麼我想知道它是如何工作,魔術或只是發生了一些事情排隊?還是他們已經添加了自動支持那東西? –

3
 if (Url.IsLocalUrl(returnUrl)) 
     { 
      return Redirect(returnUrl); 
     } 
     else 
     { 
      return RedirectToAction("Index", "Controller"); 
     } 
+0

我知道這個代碼,問題是如果我需要使用它,或者如果這是在MVC5的框架中處理的話 –

2

要回答你的關於如何設置重定向Url的第一個問題,它在Startup.Auth.cs中配置,它從Startup.cs調用,並且標記有OWIN框架在app啓動時可能查找的屬性以及bo th文件partial擴展了Startup類。

Startup.Auth.cs有配置驗證選項一類,通常有下面的代碼

public partial class Startup 
{ 
    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 
    public void ConfigureAuth(IAppBuilder app) 
    { 
     // Enable the application to use a cookie to store information for the signed in user 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/Login"), 
      CookieSecure = CookieSecureOption.Always 
     }); 
     // Use a cookie to temporarily store information about a user logging in with a third party login provider 
     app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

     // .... 
     // I deleted code which is commented out if you selected "Individual accounts" 
     // if you created the site project using the VS 2013 wizard 
     // ... 
    } 
} 

我加入了CookieSecure選項,以確保簽署的Cookie和建議作爲一個良好的安全習慣,除此之外其鍋爐板碼。

關於CookieAuthenticationOptions的更多文檔如果您需要它。

+1

如果你的整個網站是HTTPS,那麼使用CookieSecureOption.Always是多餘的。此外,從文檔中,這也迫使您使用HTTPS進行本地開發。默認情況下它是'CookieSecureOption.SameAsRequest'。因此,如果您的網站使用HTTPS,建議不要更改'CookieSecure'屬性,因爲默認設置足夠安全。 – QuantumHive

2

正如Sandeep Phadke所說,由於startup.Auth.cs中的配置,returnUrl參數被填充。

CookieAuthenticationOptions具有屬性ReturnUrlParameter,該屬性默認設置爲「returnUrl」。這就是爲什麼它看起來像魔術的原因。你可以將其更改爲任何你想要的:

app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
     LoginPath = new PathString("/Account/Login"), 
     ReturnUrlParameter = "returnTo" 
    }); 

然後你可以登錄的AccountController,行動更改爲:

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