How to redirect work to returnUrl in Asp.Net MVC5

I started a new MVC 5 site using the new Asp.Net Identity with Owin. In my "account" controller, which has the [Authorize] attribute, I have fairly standard actions;

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

My question is about the behavior of returnUrl, the above code works in the sense that if the user is not logged in and calls the action in the controller with the [Authorize] attribute, he is sent to the input of the action above, and then returned to the controller / action that was requested . What’s great, BUT how? And is it safe?

In this article on β€œ Preventing Open Redirect Attacks ” (for earlier versions of Asp.Net MVC), it is recommended that you check returnUrl that it is a local url before doing the redirection, that there is something that I would have to do or now it processed by the frame?

Cheers, Ola

+8
redirect login asp.net-mvc asp.net-mvc-5
source share
4 answers

You need to check if the url really uses the local method (it is not automatically processed by the framework): 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); } 
+13
source share
  if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index", "Controller"); } 
+3
source share

To answer your first question about how the redirect URL is configured, it is configured in Startup.Auth.cs , which is called from Startup.cs and marked with an attribute that is probably viewed by the OWIN map when the application starts, and both files are partial extend the Startup class.

In Startup.Auth.cs there is a class for setting authentication parameters and usually has the following code

 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 // ... } } 

I have added the CookieSecure parameter to ensure that cookies are signed, and this is recommended as a good security practice, other than the code of its boiler room.

More documentation on CookieAuthenticationOptions if you want to.

+2
source share

As Sandeep Fadke said, the returnUrl parameter is populated due to the configuration in startup.Auth.cs.

CookieAuthenticationOptions has a ReturnUrlParameter property, which is set to "returnUrl" by default. That's why it looks like magic. You can change it to whatever you want:

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

Then you can change the LoginController Login-Action to:

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

All Articles