[英]Remote Require HTTPS MVC 5
我具有以下屬性,以確保遠程站點頁面以https模式打開。
public class RemoteRequireHttpsAttribute : RequireHttpsAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentException("Filter Context");
}
if (filterContext != null && filterContext.HttpContext != null)
{
if (filterContext.HttpContext.Request.IsLocal)
{
return;
}
else
{
string val = ConfigurationManager.AppSettings["RequireSSL"].Trim();
bool requireSsl = bool.Parse(val);
if (!requireSsl)
{
return;
}
}
}
base.OnAuthorization(filterContext);
}
}
本地開發現在正常工作,因為我不希望它以https模式打開。
開發人員站點以https模式打開頁面-此處沒有問題(單節點)。
我正在設置的生產(負載平衡-2個節點)站點在哪里給我以下錯誤。 請注意,開發和生產站點具有相同的設置和web.config
頁面未正確重定向
Firefox已檢測到服務器正在以永遠無法完成的方式重定向對該地址的請求。
有時可能是由於禁用或拒絕接受Cookie引起的。
開發站點網址類似於http://dev.datalab.something.org
產品站點網址類似於http://datalab.something.org
這是電話
[RemoteRequireHttps]
public ActionResult Index(string returnUrl, string error)
我在這里想念什么?
更新1:我的管理員已確認在便攜式平衡器evel上已設置SSL終端。 我已經查看了iis站點設置,但沒有看到https綁定。 我只看到http綁定。 他是否還需要設置https綁定?
更新2: @AlexeiLevenkov向我指出了正確的方向, 這篇文章有我使用的代碼,並且可以正常工作。 將代碼移動到單獨的答案中。
您的網站位於執行SSL終止的負載均衡器之后-因此,無論用戶看到什么,所有傳入您網站的流量都是HTTP。 這將導致您的代碼始終嘗試重定向到HTTPS版本,從而導致無限循環。
修復選項:
x-forwarded-for
是通常用於此目的的。 您可能需要與網絡管理員聯系,以查看是否使用了這些標頭或是否需要一些其他配置 如何調查此類問題:
並不是我反對編寫漂亮的自定義屬性,是否可能在web.config中執行重定向並使用可用於web.config的轉換將以下啟用值從false更改為true進行生產部署是否有意義?
<rewrite>
<rules>
<rule name="SSL_ENABLED" enabled="false" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
如@AlexeiLevenkov所述,將修復程序移到單獨的答案中。
public class RemoteRequireHttpsAttribute : RequireHttpsAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentException("Filter Context");
}
if(filterContext.HttpContext != null)
{
if (filterContext.HttpContext.Request.IsSecureConnection)
{
return;
}
var currentUrl = filterContext.HttpContext.Request.Url;
if (currentUrl.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.CurrentCultureIgnoreCase))
{
return;
}
if (string.Equals(filterContext.HttpContext.Request.Headers["X-Forwarded-Proto"], "https", StringComparison.InvariantCultureIgnoreCase))
{
return;
}
if (filterContext.HttpContext.Request.IsLocal)
{
return;
}
var val = ConfigurationManager.AppSettings["RequireSSL"].Trim();
var requireSsl = bool.Parse(val);
if (!requireSsl)
{
return;
}
}
base.OnAuthorization(filterContext);
}
}
我也更新了ExitHttps屬性。 這有類似的問題...
public class ExitHttpsAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentException("Filter Context");
}
if (filterContext.HttpContext == null)
{
return;
}
var isSecure = filterContext.HttpContext.Request.IsSecureConnection;
var currentUrl = filterContext.HttpContext.Request.Url;
if (!isSecure && currentUrl.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.CurrentCultureIgnoreCase))
{
isSecure = true;
}
if (!isSecure && string.Equals(filterContext.HttpContext.Request.Headers["X-Forwarded-Proto"], "https", StringComparison.InvariantCultureIgnoreCase))
{
isSecure = true;
}
if (isSecure)
{
//in these cases keep https
// abort if a [RequireHttps] attribute is applied to controller or action
if (filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof (RequireHttpsAttribute), true).Length > 0)
{
isSecure = false;
}
if (isSecure && filterContext.ActionDescriptor.GetCustomAttributes(typeof (RequireHttpsAttribute), true).Length > 0)
{
isSecure = false;
}
// abort if a [RetainHttps] attribute is applied to controller or action
if (isSecure && filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof (RetainHttpsAttribute), true).Length > 0)
{
isSecure = false;
}
if (isSecure && filterContext.ActionDescriptor.GetCustomAttributes(typeof (RetainHttpsAttribute), true).Length > 0)
{
isSecure = false;
}
// abort if it's not a GET request - we don't want to be redirecting on a form post
if (isSecure && !String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
isSecure = false;
}
}
if (!isSecure)
{
return;
}
// redirect to HTTP
var url = "http://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult(url);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.