2010-06-19 23 views
11

me encuentro con un problema con lo que debería ser una forma de inicio de sesión simple en ASP.NET MVC 2. Esencialmente mi formulario se ve un poco algo como esto:ASP.NET MVC - HTML.BeginForm y SSL

using (Html.BeginForm("LogOn", "Account", new { area = "Buyers" }, FormMethod.Post, new { ID = "buyersLogOnForm" })) 

tengo un filtro RequiresHTTPS en el método de acción LogOn pero cuando se ejecuta recibo el siguiente mensaje

el recurso solicitado sólo se puede acceder a través de SSL

En este punto, la única solución que funcionó fue a pasar en un htmlattribute acción adicional de la siguiente manera:

var actionURL = "https://" + Request.Url.Host + Request.Url.PathAndQuery; 
using (Html.BeginForm("LogOn", "Account", new { area = "Buyers" }, FormMethod.Post, new { ID = "buyersLogOnForm", @action = actionURL })) 

Aunque esto funciona Me pregunto a) por qué estoy viendo este tema en primer lugar, y b) si hay ¿Es una forma más sencilla de publicar en https desde una página http?

[Editar]

yo, hubiera declarado que el menú desplegable de inicio de sesión estará disponible en muchas páginas públicas. No quiero que todas mis páginas sean HTTPS. Por ejemplo, mi página de esperanza, que CUALQUIERA puede ver, no debe estar basada en HTTPS. Esencialmente, necesito especificar el protocolo en mi formulario, pero no tengo ni idea de cómo hacerlo, o si es posible.

Agradecería cualquier consejo/sugerencia. Gracias de antemano

JP

Respuesta

11

Usted podría utilizar

<form action =" <%= Url.Action(
"action", 
"controller", 
ViewContext.RouteData.Values, 
"https" 
) %>" method="post" > 
+2

El problema con esto es que no hay FormContext creado para su formulario, por lo que todos los helpers de entrada HTML no agregarán atributos de validación adjuntos a sus modelos de vista ... –

+0

Consulte la respuesta a continuación por Brad J. ¡Esto NO es seguro! – Null

6

utilizar el atributo [RequireHttps] tanto en la acción que hace que la forma y la envías.

+1

El menú desplegable de inicio de sesión estará disponible en muchas páginas públicas. No quiero que todas mis páginas sean HTTPS. Por ejemplo, mi página de esperanza, que CUALQUIERA puede ver, no debe estar basada en HTTPS –

+3

Se puede disuadir a los usuarios de ingresar su nombre de usuario y contraseña en una página de inicio de sesión donde el candado no está visible en su navegador. Se considera una buena práctica usar HTTPS en las páginas de inicio de sesión. –

+0

Definitivamente veo tu punto. Sin embargo, creo que esta es una decisión de diseño y no necesariamente algo que debería ser una restricción técnica. Tome Twitter como un ejemplo de cómo un menú desplegable (desde una página que no sea https) mejora la experiencia de inicio de sesión del usuario, sin requerir una carga de página completa para dos campos simples. –

4

Actualización: Revisar los comentarios a continuación sobre las vulnerabilidades de seguridad de este enfoque antes de considerar el uso de este código.

Encontré que funcionaba un híbrido de ejemplos de código de JP y Malcolm.

using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @action = Url.Action("Login","Account",ViewContext.RouteData.Values,"https") })) 

Todavía me sentí un poco hacky, así que creé un ayudante de BeginForm personalizado. El asistente personalizado es más limpio y no requiere https cuando se ejecuta localmente.

public static MvcForm BeginFormHttps(this HtmlHelper htmlHelper, string actionName, string controllerName) 
    { 
     TagBuilder form = new TagBuilder("form"); 
     UrlHelper Url = new UrlHelper(htmlHelper.ViewContext.RequestContext); 

     //convert to https when deployed 
     string protocol = htmlHelper.ViewContext.HttpContext.Request.IsLocal == true? "http" : "https"; 

     string formAction = Url.Action(actionName,controllerName,htmlHelper.ViewContext.RouteData.Values,protocol); 
     form.MergeAttribute("action", formAction); 

     FormMethod method = FormMethod.Post; 
     form.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true); 

     htmlHelper.ViewContext.Writer.Write(form.ToString(TagRenderMode.StartTag)); 

     MvcForm mvcForm = new MvcForm(htmlHelper.ViewContext); 

     return mvcForm; 
    } 

Ejemplo de uso:

@using (Html.BeginFormHttps("Login", "Account")) 
+0

Realmente no es seguro hacer esto. No hay razón en este día y edad para que todas las páginas no puedan ser https. –

+0

¿Puede ampliar por qué esto no es seguro? –

+0

Porque es vulnerable a un ataque de hombre en el medio. La página no encriptada puede verse comprometida en tránsito y la URL modificada para apuntar a otro sitio. Como el usuario no puede ver la URL en la que está publicando, no hay forma de que el usuario sepa que esto sucedió. Aquí hay un ejemplo http://resources.infosecinstitute.com/mitm-using-sslstrip/ –