2010-06-19 6 views
11

Je rencontre un problème avec ce qui devrait être une forme simple d'ouverture de session dans ASP.NET MVC 2. Essentiellement ma forme ressemble un peu quelque chose comme ceci:ASP.NET MVC - Html.BeginForm et SSL

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

J'ai un filtre RequiresHTTPS sur la méthode d'action LogOn mais quand il exécute je reçois le message suivant

la ressource demandée ne peut être accessible via SSL

A ce stade, la seule solution qui a fonctionné était de passer dans un htmlattribute d'action supplémentaire comme suit:

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

Bien que cela fonctionne, je me demande a) pourquoi je vois cette question en premier lieu et b) si est un moyen plus simple de poster sur https depuis une page http?

[Modifier]

je aurais dû déclaré que le menu déroulant d'ouverture de session sera disponible sur de nombreuses pages publiques. Je ne veux pas que toutes mes pages soient HTTPS. Par exemple, ma page d'espoir - que N'IMPORTE QUI peut voir - ne devrait pas être basée sur HTTPS. Essentiellement, je dois spécifier le protocole dans mon formulaire, mais je n'ai aucune idée de comment le faire, ou si c'est possible.

J'apprécierais n'importe quels conseils/suggestions. Merci à l'avance

JP

Répondre

11

Vous pouvez utiliser

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

Le problème avec ceci est qu'il n'y a pas de FormContext créé pour votre formulaire, donc tous les helpers de saisie Html n'ajouteront pas d'attributs de validation attachés à vos modèles de vue ... –

+0

Voir la réponse ci-dessous par Brad J. Ce n'est PAS sécurisé! – Null

6

Utilisez l'attribut [RequireHttps] à la fois sur l'action qui rend la forme et celui que vous envoyez des messages.

+1

La liste déroulante de connexion sera disponible sur de nombreuses pages publiques. Je ne veux pas que toutes mes pages soient HTTPS. Par exemple, ma page d'espoir - que N'IMPORTE QUI peut voir - ne devrait pas être basée sur HTTPS –

+3

Les utilisateurs peuvent être dissuadés d'entrer leur nom d'utilisateur et mot de passe sur une page de connexion sur laquelle le cadenas n'est pas visible dans leur navigateur. Il est recommandé d'utiliser HTTPS sur les pages de connexion. –

+0

Je vois vraiment ce que vous voulez dire. Cependant, je crois que c'est une décision de conception et pas nécessairement quelque chose qui devrait être une contrainte technique. Prenez Twitter comme un exemple d'où une telle liste déroulante (à partir d'une page non https) améliore l'expérience de connexion de l'utilisateur - ne nécessitant pas un chargement complet de la page pour deux champs simples. –

4

Mise à jour: Passez en revue les commentaires ci-dessous au sujet des failles de sécurité de cette approche avant d'envisager l'utilisation de ce code. J'ai trouvé qu'un hybride d'exemples de code de JP et Malcolm fonctionnait. Je me sentais encore un peu hacky mais j'ai créé un assistant BeginForm personnalisé. L'assistant personnalisé est plus propre et ne nécessite pas de https lorsqu'il est exécuté localement.

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

Exemple d'utilisation:

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

Ce n'est vraiment pas sécurisé de le faire. Il n'y a aucune raison de nos jours que toutes les pages ne puissent pas être https. –

+0

Pouvez-vous expliquer pourquoi ce n'est pas sécurisé? –

+0

Parce qu'il est vulnérable à une attaque man-in-the-middle. La page non cryptée peut être compromise en transit et l'URL modifiée pour pointer vers un autre site. Étant donné que l'utilisateur ne peut pas voir l'URL à laquelle vous envoyez des messages, l'utilisateur ne peut pas savoir que cela s'est produit. Voici un exemple http://resources.infosecinstitute.com/mitm-using-sslstrip/ –