2010-01-04 16 views
5

Esta es la situación ...sesiones sin cookies y cross-site mensajes de forma

Sitio 1) aplicación ASP.NET MVC para los clientes para iniciar sesión, ver y pagar facturas, etc. Este sitio está utilizando ASP sesiones sin cookies para permitir sesiones múltiples para ejecutar en navegadores con pestañas.

Sitio 2) Sitio web corporativo con contenido estático estándar. Esto tendrá un pequeño formulario en la parte superior de cada página con un formulario de nombre de usuario/contraseña que se publicará en la aplicación MVC.

Al publicar en la aplicación MVC, se genera una nueva sesión y el sitio devuelve una redirección 302 con la ID de sesión en la URL (como se esperaba). El controlador tiene dos métodos de inicio de sesión, uno para manejar un GET, uno para manejar un POST. Debido a la redirección, está golpeando el método GET y pierde los valores de forma.

Al cambiar el método en el sitio corporativo para hacer un formulario GET en lugar de un POST, el nombre de usuario y la contraseña se conservan en la cadena de consulta después de la redirección y pude manejar las solicitudes de esa manera, pero preferiría hacer un POST y no pasa esa información en la URL.

Mi intuición dice que implementar algún tipo de HttpHandler personalizado me permitiría hacer esto, pero no estoy seguro de dónde podría vincularme con la creación de la sesión. Un punto de interrupción en Session_Start en global.asax muestra que la ID de la sesión ya se ha almacenado y que la redirección ya ocurrió en ese punto.

Respuesta

2

Creo que encontré dónde estaba ocurriendo el redireccionamiento, así como una posible solución. La interfaz ISessionIDManager tiene un método SaveSessionID con un parámetro "out bool redirected". Parece que cuando se crea una nueva sesión, el administrador de sesión predeterminado reescribe la URL dentro de este método y hace una redirección. Jugué con la implementación de mi propio ISessionIDManager y pude suprimir el redireccionamiento, pero no hay forma (que yo pudiera decir) de insertar el ID de sesión en el URL para la sesión sin cookies sin hacer el redireccionamiento. Server.Transfer no está permitido en ese momento en el ciclo de vida de la solicitud. Lo intenté pero recibí un mensaje de "Error al ejecutar la solicitud de un niño".

Más tarde, encontré este artículo en Enabling POST in cookieless ASP.NET Applications. Básicamente al vincularse al evento Application_EndRequest, puede detectar la redirección, borrar la respuesta y falsificar una publicación de formulario en la nueva URL que contiene la ID de la sesión.

void MvcApplication_EndRequest(object sender, EventArgs e) 
{ 

    HttpApplication application = (HttpApplication)sender; 

    if (application.Request.Form["CorpLogin"] == "1" 
     && application.Response.RedirectLocation != null 
     && application.Response.IsRequestBeingRedirected) 
    { 

     StringBuilder build = new StringBuilder(); 
     build.Append("<html>\n<body>\n<form name='Redirect' method='post' action='"); 
     build.Append(application.Response.RedirectLocation); 

     build.Append("' id='Redirect' >"); 
     foreach (string key in application.Request.Form) 
     { 
      if (key != "CorpLogin") 
       build.Append(string.Format("\n<input type='hidden' name='{0}' value = '{1}'>", (string)key, application.Request.Form[(string)key])); 
     } 

     build.Append("\n<noscript><h2>Object moved <input type='submit' value='here'></h2></noscript>"); 
     build.Append(@"</form> 
     <script language='javascript'> 
     <!-- 
     document.Redirect.submit(); 
     // --> 
     </script> 
     "); 
     build.Append("</body></html>"); 

     application.Response.Clear(); 
     application.Response.ClearHeaders(); 
     application.Response.Output.Flush(); 

     application.Response.Write(build.ToString()); 

    } 
} 

Esto no es una solución ideal en mi humilde opinión, pero podría ser lo suficientemente viable para cumplir con los requisitos.

+0

¿Podría mostrar cómo detectó la redirección en EndRequest y borró la respuesta? Necesito solo este bit, creo ... –

0

Cuando el sitio MVC emite el redireccionamiento, ¿lo está manejando usted mismo con un controlador o su proveedor de membresía lo está enrutando automáticamente?

Si puede interceptar la solicitud antes de la redirección, puede colocar el nombre de usuario y la contraseña en la variable TempData y procesarla después de la redirección.

+0

Se está redirigiendo automáticamente. –

+0

¿Qué controlador/acción publica el sitio remoto cuando el usuario intenta iniciar sesión? –

+0

Ahora mismo estoy usando el servidor web VS, por lo que el formulario tiene una publicación en "http: // localhost: 2600/Home/Login" y el método parece ... '[HttpPost] public ActionResult Login (HomeLoginData loginData) { // snip } ' pero nunca llega debido a la redirección con la nueva ID de sesión. Por ejemplo, el sitio corporativo forma POST para http: // localhost: 2600/Home/Login y obtengo un redireccionamiento 302 a http: // localhost: 2600 /% 28S% 28lkcfoer1mb1gbf55hi1bqsbn% 29% 29/Inicio/Login –

0

Usted está buscando un Server.Transfer equivalent in MVC (véase la respuesta de Simón.)

Es como Request.Redirect sino simplemente transfiere el procesamiento de .NET a otra página. También permite mantener las variables de forma incluso en POST entre transferencias (en este caso, un RouteValueDictionary).

EDIT: (respuesta a su comentario # 1)

Aquí está un ejemplo de Forms Authentication with MVC. Sin saber las partes internas de su mecanismo de autorización, no estoy del todo seguro. En cualquier punto del proceso "DoLogin", podría realizar una transferencia en lugar de una redirección.

+0

¿Dónde estaría? ¿Puedo interceptar la primera publicación del formulario sin sesión para evitar la redirección 302 predeterminada una vez creada la sesión? –

+0

Ver mi edición - quizás te indique la dirección correcta. –

Cuestiones relacionadas