【问题标题】:Check for SSL when hosted in Rackspace (Mosso) Cloud在 Rackspace (Mosso) Cloud 中托管时检查 SSL
【发布时间】:2011-01-06 19:44:44
【问题描述】:

我正在使用 Request.IsSecureConnection 检查 SSL 并在适当的地方进行重定向。在 Rackspace 的云上运行我的 asp.net 网站时,服务器在 SSL 集群后面运行,因此 IsSecureConnection 将始终返回 false。检查 url 是否包含“https://”、始终为 false、检查端口等也是如此。因此网站陷入了大重定向循环。

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

【问题讨论】:

  • 并不是说它与这个问题有任何关系,但我很欣赏使用 const 来处理像“http”和“https”这样的简单字符串。

标签: c# .net vb.net ssl


【解决方案1】:

虽然很难检查是否启用了 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>

您可以在 ASP.NET 中强制使用 SSL:

<%@ 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>

【讨论】:

  • 谢谢,我搜索了帮助文件,但我自己没有找到。回想起来,我认为循环 ServerVariables 集合并查看其中的内容会很聪明。
  • 我很好奇,“HTTP_CLUSTER-HTTPS”是错字吗?你有一个有两个下划线,一个有一个下划线和一个破折号。
  • link 重写规则将破折号替换为下划线,因此它可能无关紧要。根据我的直接经验,它似乎完全按照此处所示或两个下划线工作。
【解决方案2】:

我在使用 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"));
    }
}

【讨论】:

  • 那么为什么需要实现RequireHttpsAttribute类的替换呢?
  • @Corgalore 好吧,因为我不能简单地替换 HttpRequest.IsSecureConnection (一个属性),这是内置 RequireHttpsAttribute 正在检查的内容。我在 HttpRequest 上做了一个 extension,称为 IsSecureConnection()(一种方法)。因此,我的替换 RequireHttpAttribute 改为检查我的扩展。
猜你喜欢
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多