2010-06-19 107 views
11

我遇到什麼應該在ASP.NET MVC一個簡單的登錄表單的問題2.本質上我的形式看起來有點像這樣:ASP.NET MVC - HTML.BeginForm和SSL

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

我在登錄操作方法的RequiresHTTPS過濾器,但在執行時我收到以下消息

所請求的資源只能 通過SSL訪問

此時只有工作的解決方案是一個額外的行動htmlattribute通過如下:

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

雖然這工作我不知道一)爲什麼我在第一時間看到了這個問題,並b)如是從http頁面發佈到https的更直接的方式?

[編輯]

我應該指出,在登錄下拉菜單將可在許多公共頁面。我不希望所有的網頁都是HTTPS。例如,我希望的頁面 - 任何人都可以看到 - 不應該是基於HTTPS的。基本上我需要在表單中指定協議,但不知道如何做,或者如果可能。

我將不勝感激任何意見/建議。 在此先感謝

JP

回答

11

你可以使用

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

問題在於沒有爲您的表單創建FormContext,所以所有的Html輸入幫助程序都不會添加驗證屬性附加到您的視圖模型... – 2012-02-10 21:50:07

+0

請參閱下面的答案由布拉德J.這是不安全的! – Null 2015-04-17 04:07:42

6

使用雙方的動作[RequireHttps]屬性呈現形式和您要發佈帖子的人。

+1

的登錄下拉菜單將可在許多公共頁面。我不希望所有的網頁都是HTTPS。例如,我的希望頁面 - 任何人都可以看到 - 不應該是基於HTTPS的 – 2010-06-19 18:25:58

+3

用戶可能會被阻止在登錄頁面輸入他們的用戶名和密碼,掛鎖在瀏覽器中不可見。在登錄頁面上使用HTTPS被認爲是很好的做法。 – 2010-06-19 18:38:06

+0

我絕對看到你的觀點。但是,我認爲這是一個設計決定,不一定是應該成爲技術約束的東西。以Twitter爲例,這種下拉(來自非https頁面)增強了用戶登錄體驗 - 不需要對兩個簡單字段進行整頁加載。 – 2010-06-19 21:27:36

4

更新:考慮使用此代碼之前查看低於這一方法的安全漏洞的評論。

我發現JP和Malcolm的代碼示例的混合工作。

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

儘管如此,我仍然覺得有點hacky,所以我創建了一個自定義的BeginForm助手。在本地運行時,自定義助手更清晰並且不需要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; 
    } 

用法示例:

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

這樣做確實不安全。在這個時代沒有理由說所有的頁面都不能是https。 – 2013-08-05 02:07:46

+0

你可以擴展爲什麼這不安全嗎? – 2013-08-06 17:47:25

+0

因爲它容易受到中間人攻擊。未加密的頁面可能會在傳輸過程中受到損害,並且URL會被修改爲指向某人的網站。由於用戶無法看到要發佈的網址,因此用戶無法知道發生了這種情況。這裏是一個例子http://resources.infosecinstitute.com/mitm-using-sslstrip/ – 2013-08-06 18:13:59