Cómo redirige a returnUrl en Asp.Net MVC5

Comencé un nuevo sitio MVC 5, usando la nueva Asp.Net Identity con Owin. En mi controlador de "cuenta" que tiene el atributo [Autorizar], tengo acciones bastante estándar;

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

// POST: /User/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task 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);
        }

Mi pregunta es con respecto al comportamiento returnUrl, el código anterior funciona en el sentido de que, si un usuario no inicia sesión y llama a una acción en un controlador que tiene el atributo [Autorizar], se envía a las acciones de inicio de sesión anteriores y luego regresó al controlador/acción que se solicitó. Lo cual es genial, PERO ¿cómo? Y es seguro?

En este artículo sobre " Cómo evitar ataques de redirección abiertos " ( para versiones anteriores de Asp.Net MVC), la recomendación es verificar si returnUrl es una url local antes de hacer la redirección, ¿es algo que todavía debo hacer o que ahora está manejado por el marco?

Aclamaciones, Ola

0

4 Respuestas

You need to check if the url is local indeed using this method (it is not handled by the framework automatically): 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
agregado
¿Tiene alguna fuente para la información que no se maneja? Parece extraño que pongan la funcionalidad para redirigir a returnUrl automáticamente pero no sigan sus propias pautas al hacerlo. De ahí la pregunta original.
agregado el autor Ola Karlsson, fuente
Sí, supongo que sería una opción. Sé que returnUrl nunca se usa en mi acción, pero aún así el sitio redirige correctamente, ¿por qué me pregunto cómo funciona, magia o simplemente que algo pasa para alinearme? ¿O es que han agregado soporte automático para ¿Esas cosas?
agregado el autor Ola Karlsson, fuente
Encontré esto que habla de ello blogs.msdn.com/b/webdev/archive/2013/07/03/… pero no estoy siendo mucho más inteligente, debo admitir.
agregado el autor Ola Karlsson, fuente
¿Por qué no tratas de manipular el returnUrl y ver qué pasa? Por cierto, en su código nunca se usa el argumento returnUrl .
agregado el autor Marthijn, fuente
De hecho, es un comportamiento bastante extraño. No puedo encontrar nada sobre el manejo de returnUrl en mvc 5, así que supongo que debería funcionar igual que en las versiones anteriores.
agregado el autor Marthijn, fuente
Vea el último fragmento de código en ese artículo: return RedirectToLocal (returnUrl); Supongo que esta función realiza el código de validación de la url local en mi respuesta.
agregado el autor Marthijn, fuente
       if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Controller");
        }
0
agregado
Conozco este código, las preguntas son si necesito usarlo o si esto se maneja en el marco para MVC5
agregado el autor Ola Karlsson, fuente

Para responder a su primera pregunta sobre cómo se configura la URL de redireccionamiento, se configuró en Startup.Auth.cs que se llama desde Startup.cs y se marca con un atributo que es probablemente fue buscado por el framework OWIN en el inicio de la aplicación y ambos archivos partial extienden una clase Startup .

En Startup.Auth.cs hay una clase para configurar las opciones de autenticación y generalmente tiene el siguiente código

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

Agregué la opción CookieSecure para asegurar que se firmaran las cookies y que se recomienda como una buena práctica de seguridad, aparte de su código de placa de caldera.

Más documentación en CookieAuthenticationOptions si lo desea.

0
agregado
Si su sitio web completo está en HTTPS, entonces es redundante utilizar CookieSecureOption.Siempre . Además, de la documentación, esto obliga a usar HTTPS para el desarrollo local también. Por defecto es CookieSecureOption.SameAsRequest . Por lo tanto, si su sitio web está en HTTPS, se recomienda no cambiar la propiedad CookieSecure , ya que la configuración predeterminada es lo suficientemente segura.
agregado el autor QuantumHive, fuente

Como dijo Sandeep Phadke, el parámetro returnUrl está lleno, debido a la configuración en el inicio. Auth.cs.

El CookieAuthenticationOptions tiene una propiedad ReturnUrlParameter que está configurada por defecto en "returnUrl". Esa es la razón, por qué parece magia. Puedes cambiarlo a lo que quieras:

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

Luego puede cambiar la acción de inicio de sesión de AccountController a:

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