2010-01-19 48 views
6

我正在使用Request.IsSecureConnection检查SSL并在适当的位置重定向。当在Rackspace的云上运行我的asp.net网站时,服务器运行在SSL集群后面,因此IsSecureConnection将始终返回false。检查URL是否包含“https://”,始终为false,检查端口等等也是如此。因此,该网站被卡在大的重定向循环中。托管在Rackspace(Mosso)Cloud时检查SSL

是否有其他方法检查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 
+0

不是说它与这个问题有什么关系,但是你对于使用const的简单字符串如'http'和'https'有很好的理解。 – 2011-12-03 19:46:31

回答

5

虽然很难检查SSL是否参与解决问题的办法是强制SSL。

RackspaceCloud Support knowledge base

你可以重新写在web.config中的URL:

<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> 
+0

谢谢,我搜索了帮助文件,并没有发现我自己。回想起来,我想如果循环ServerVariables集合并看看那里有什么会很聪明。 – 2010-01-19 14:30:59

+0

我很好奇,是“HTTP_CLUSTER-HTTPS”的错字?你有一个有两个下划线,一个有下划线和一个短划线。 – 2010-02-24 16:18:29

+0

[link](http://learn.iis.net/page.aspx/465/url-rewrite-module-configuration-reference/#Rule_action)重写规则用下划线代替破折号,所以它可能没关系。看起来像这里所显示的工作或者我的直接经验中的两个下划线。 – philw 2011-04-19 21:28:51

5

我就遇到了这个与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")); 
    } 
} 
+0

那么为什么有必要实现RequireHttpsAttribute类的替代? – Corgalore 2011-06-02 18:39:02

+0

@Corgalore那么,因为我不能简单地替换HttpRequest.IsSecureConnection(一个属性),这是内置的RequireHttpsAttribute正在检查的内容。我在HttpRequest上调用了一个名为IsSecureConnection()(方法)的*扩展*。因此,我的替换RequireHttpAttribute改为检查我的扩展。 – 2011-06-03 17:51:34