2010-06-19 1 views
11

ich ein Problem mit dem ich begegnet, was eine einfache Anmeldeformular in ASP.NET MVC sollte 2. Im Wesentlichen sieht meine Form ein wenig etwas wie folgt aus:ASP.NET MVC - Html.BeginForm und SSL

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

ich habe einen RequiresHTTPS Filter auf der Methode LogOn Aktion, aber wenn es ausführt, erhalte ich die folgende Meldung

die angeforderte Ressource kann nur über SSL zugegriffen werden

An dieser Stelle ist die einzige Lösung, die arbeitete, war in einem extra Aktion htmlattribute passieren wie folgt:

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

Das funktioniert zwar, ich frage mich), warum ich sehe dieses Problem in erster Linie und b) wenn es ist eine einfachere Möglichkeit, von einer http-Seite auf https zu schreiben?

[Bearbeiten]

Ich hätte festgestellt, dass die Anmeldung Drop-Down auf vielen öffentlichen Seiten zur Verfügung stehen wird. Ich möchte nicht, dass alle meine Seiten HTTPS sind. Zum Beispiel sollte meine Hoffnungsseite - die JEDER sehen kann - nicht HTTPS-basiert sein. Im Wesentlichen muss ich das Protokoll in meiner Form spezifizieren, aber habe keine Idee, wie man das macht, oder wenn es möglich ist.

Ich würde mich über Ratschläge/Vorschläge freuen. Vielen Dank im Voraus

JP

Antwort

11

könnten Sie

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

Das Problem damit ist, dass kein FormContext für Ihr Formular erstellt wird, so dass alle Html-Eingabehilfen keine Validierungsattribute hinzufügen, die an Ihre Ansichtsmodelle angehängt sind ... –

+0

Siehe die Antwort unten von Brad J. Dies ist NICHT sicher! – Null

6

Verwenden Sie das [RequireHttps] Attribut sowohl auf der Aktion, die die Form und die, die Sie eine Mitteilung verfassen, macht zu.

+1

Die Anmeldung Drop-Down auf vielen öffentlichen Seiten zur Verfügung. Ich möchte nicht, dass alle meine Seiten HTTPS sind. Zum Beispiel sollte meine Hoffnungsseite - die JEDER sehen kann - nicht HTTPS-basiert sein. –

+3

Benutzer könnten davon abgeraten werden, ihren Benutzernamen und ihr Passwort auf einer Anmeldeseite einzugeben, auf der das Vorhängeschloss in ihrem Browser nicht sichtbar ist. Es wird empfohlen, HTTPS auf Anmeldeseiten zu verwenden. –

+0

Ich sehe definitiv Ihren Standpunkt. Ich glaube jedoch, dass dies eine Design-Entscheidung ist und nicht notwendigerweise etwas, was eine technische Einschränkung sein sollte. Nehmen Sie Twitter als Beispiel dafür, wo ein solches Dropdown (von einer Nicht-HTTPS-Seite) die Benutzeranmeldung verbessert - für zwei einfache Felder ist keine vollständige Seitenladung erforderlich. –

4

Update verwenden: Überprüfen Sie die folgenden Erläuterungen zu den Sicherheitslücken dieses Ansatzes vor der Verwendung dieses Codes berücksichtigen.

Ich fand, dass eine Mischung aus JP und Malcolms Codebeispielen funktionierte.

Noch fühlte ich mich ein bisschen hacky, also habe ich einen benutzerdefinierten BeginForm-Helfer erstellt. Der benutzerdefinierte Helper ist sauberer und erfordert bei lokaler Ausführung kein https.

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

Beispiel Nutzung:

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

Es ist wirklich nicht sicher, dies zu tun. Es gibt keinen Grund in der heutigen Zeit, dass alle Seiten nicht https sein können. –

+0

Können Sie näher erläutern, warum dies nicht sicher ist? –

+0

Weil es anfällig für einen Man-in-the-Middle-Angriff ist. Die unverschlüsselte Seite kann während der Übertragung kompromittiert werden, und die URL wurde so geändert, dass sie auf eine andere Website verweist. Da der Benutzer die URL, zu der Sie einen Beitrag veröffentlichen, nicht sehen kann, kann der Benutzer nicht wissen, dass dies geschehen ist. Hier ist ein Beispiel http://resources.infosecinstitute.com/mitm-using-sslstrip/ –