Я использую Запрос. IsSecureConnection для проверки на SSL и перенаправляющий в соответствующих случаях. При выполнении моего веб-сайта asp.net на облаке Rackspace сервер работает позади кластера SSL, таким образом, IsSecureConnection будет всегда возвращать false. То же идет для проверки, содержит ли URL "https://", всегда ложь, проверяя порт, и т.д. Таким образом, веб-сайт застревает в большом цикле перенаправления.
Там другой путь состоит в том, чтобы проверить на SSL и перенаправление в соответствующих случаях? Кто-либо, который на самом деле сделал это на облаке Rackspace?
Public Class SecurityAwarePage
Inherits Page
Private _requireSSL As Boolean = False
Public Property RequireSSL() As Boolean
Get
Return _requireSSL
End Get
Set(ByVal value As Boolean)
_requireSSL = value
End Set
End Property
Private ReadOnly Property IsSecure() As Boolean
Get
Return Request.IsSecureConnection
End Get
End Property
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
PushSSL()
End Sub
Private Sub PushSSL()
Const SECURE As String = "https://"
Const UNSECURE As String = "http://"
If RequireSSL AndAlso Not IsSecure Then
Response.Redirect(Request.Url.ToString.Replace(UNSECURE, SECURE))
ElseIf Not RequireSSL AndAlso IsSecure Then
Response.Redirect(Request.Url.ToString.Replace(SECURE, UNSECURE))
End If
End Sub
End Class
Хотя проверить, задействован ли SSL, сложно, можно обойти эту проблему принудительно.
Из базы знаний RackspaceCloud Support:
Можно переписать URL-адреса в web.config:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_CLUSTER_HTTPS}" pattern="^on$" negate="true" />
<add input="{HTTP_CLUSTER-HTTPS}" pattern=".+" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{SCRIPT_NAME}" redirectType="SeeOther" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Можно принудительно включить SSL в ASP. NET:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">
protected void Page_Load(object sender, System.EventArgs e)
{
if(Request.ServerVariables["HTTP_CLUSTER_HTTPS"] != "on")
{
if(Request.ServerVariables.Get("HTTP_CLUSTER-HTTPS") == null)
{
string xredir__, xqstr__;
xredir__ = "https://" + Request.ServerVariables["SERVER_NAME"];
xredir__ += Request.ServerVariables["SCRIPT_NAME"];
xqstr__ = Request.ServerVariables["QUERY_STRING"];
if (xqstr__ != "")
xredir__ = xredir__ + "?" + xqstr__;
Response.Redirect(xredir__);
}
}
Response.Write("SSL Only");
}
</script>
<html>
<head id="Head1" runat="server">
<title>SSL Only</title>
</head>
<body>
</body>
</html>
Я столкнулся с той же проблемой с Rackspace Cloud и решил ее, вручную реализовав метод расширения Request.IsSecureConnection () и заменив RequireHttpsAttribute фреймворка своим собственным. Надеюсь, кто-то еще сочтет это полезным.
/// <summary>
/// Replaces framework-provided RequireHttpsAttribute to disable SSL requirement for local requests
/// and properly enforce SSL requirement when used with Rackspace Cloud's load balancer
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class RequireHttpsAttribute : FilterAttribute, IAuthorizationFilter
{
public virtual void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
if (filterContext.HttpContext.Request.IsLocal)
return;
if (!filterContext.HttpContext.Request.IsSecureConnection()) {
HandleNonHttpsRequest(filterContext);
}
}
protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext) {
// only redirect for GET requests, otherwise the browser might not propagate the verb and request
// body correctly.
if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
throw new InvalidOperationException("The requested resource can only be accessed via SSL.");
}
// redirect to HTTPS version of page
string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult(url);
}
}
public static class Extensions {
/// <summary>
/// Gets a value which indicates whether the HTTP connection uses secure sockets (HTTPS protocol). Works with Rackspace Cloud's load balancer
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static bool IsSecureConnection(this HttpRequestBase request) {
const string rackspaceSslVar = "HTTP_CLUSTER_HTTPS";
return (request.IsSecureConnection || (request.ServerVariables[rackspaceSslVar] != null || request.ServerVariables[rackspaceSslVar] == "on"));
}
/// <summary>
/// Gets a value which indicates whether the HTTP connection uses secure sockets (HTTPS protocol). Works with Rackspace Cloud's load balancer
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static bool IsSecureConnection(this HttpRequest request) {
const string rackspaceSslVar = "HTTP_CLUSTER_HTTPS";
return (request.IsSecureConnection || (request.ServerVariables[rackspaceSslVar] != null || request.ServerVariables[rackspaceSslVar] == "on"));
}
}