2010-06-19 20 views
11

ja napotykają problem z tym, co powinno być prosty formularz logowania w ASP.NET MVC 2. Zasadniczo moja forma wygląda trochę coś takiego:ASP.NET MVC - HTML.BeginForm i SSL

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

mam filtr RequiresHTTPS na metody logowania działania, ale kiedy wykonuje I pojawia się następujący komunikat

Żądany zasób można dostępne tylko za pośrednictwem protokołu SSL

W tym momencie jedynym rozwiązaniem, które działało było przejść na dodatkowym htmlattribute działania w następujący sposób:

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

Chociaż to działa Zastanawiam a) dlaczego widzę ten problem w pierwszej kolejności oraz b) jeśli istnieje jest prostszy sposób publikowania w https ze strony http?

[Edytuj]

powinienem stwierdził, że rozwijana logowania będą dostępne na wielu stronach publicznych. Nie chcę, aby wszystkie moje strony były HTTPS. Na przykład moja strona nadziei - którą KAŻDY może zobaczyć - nie powinna być oparta na HTTPS. Zasadniczo muszę podać protokół w mojej formie, ale nie mam pojęcia, jak to zrobić, lub jeśli jest to możliwe.

Byłbym wdzięczny za wszelkie porady/sugestie. góry dzięki

JP

Odpowiedz

11

Można użyć

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

Problem z tym, że nie istnieje formularz FormContext dla twojego formularza, więc wszyscy pomocnicy wejściowi HTML nie dodadzą atrybutów sprawdzania poprawności załączonych do twoich modeli widoku ... –

+0

Zobacz odpowiedź poniżej podaną przez Brada J. To NIE jest bezpieczne! – Null

6

użyć atrybutu [RequireHttps] zarówno na działania, które sprawia, że ​​formy i jeden Piszesz do.

+1

rozwijana logowania będą dostępne na wielu stronach publicznych. Nie chcę, aby wszystkie moje strony były HTTPS. Na przykład moja strona nadziei - którą KAŻDY może zobaczyć - nie powinna być oparta na HTTPS. –

+3

Użytkownicy mogą zostać zniechęceni do wprowadzenia nazwy użytkownika i hasła na stronie logowania, na której kłódka nie jest widoczna w przeglądarce. Uważa się za dobrą praktykę używanie HTTPS na stronach logowania. –

+0

Zdecydowanie rozumiem Twój punkt widzenia. Uważam jednak, że jest to decyzja projektowa, a niekoniecznie coś, co powinno być technicznym ograniczeniem. Weźmy Twitter jako przykład tego, gdzie takie rozwijanie (ze strony innej niż https) poprawia wygodę logowania użytkownika - nie wymaga pełnego załadowania strony dla dwóch prostych pól. –

4

Aktualizacja: Przejrzyj poniższe komentarze na temat luk w zabezpieczeniach tego podejścia przed rozważeniem korzystania z tego kodu.

Okazało się, że hybrydowe przykłady kodu JP i Malcolma działały.

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

Mimo to, wciąż czułem się trochę bezczelny, więc stworzyłem niestandardowego pomocnika BeginForm. Niestandardowy helper jest czystszy i nie wymaga protokołu HTTPS podczas działania lokalnie.

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

Przykład użycia:

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

Naprawdę nie jest to bezpieczne. W dzisiejszych czasach nie ma powodu, by wszystkie strony nie mogły mieć https. –

+0

Czy możesz rozwinąć, dlaczego to nie jest bezpieczne? –

+0

Ponieważ jest podatny na atak typu "man-in-the-middle". Niezaszyfrowana strona może zostać naruszona podczas przesyłania, a adres URL zmodyfikowany tak, aby wskazywał na stronę kogoś innego. Ponieważ użytkownik nie widzi adresu URL, do którego publikujesz, nie ma sposobu, aby użytkownik wiedział, że tak się stało. Oto przykład: http://resources.infosecinstitute.com/mitm-using-sslstrip/ –