2

我正在尝试构建一个使用 SSL 连接的 Web 应用程序。所以我做了一些研究,发现我可以使用 RequireHttpsAttribute 类来实现我所需要的。问题是当我使用它时,应用程序的执行会导致 310 错误(重定向太多)。我什至构建了一个自定义类来处理从 http 到 https 的切换。但这也会导致错误。

我的类来处理协议切换:

Public Class RequireSSLAttribute
    Inherits ActionFilterAttribute

    Public Property IsRequired() As Boolean

    Public Overrides Sub OnActionExecuting(filterContext As ActionExecutingContext)
        If Me.IsRequired AndAlso filterContext.HttpContext.Request.Url.Scheme <> "https" Then
            filterContext.HttpContext.Response.Redirect(filterContext.HttpContext.Request.Url.OriginalString.Replace("http:", "https:").Remove(filterContext.HttpContext.Request.Url.OriginalString.LastIndexOf(":") + 1), True)
            filterContext.Result = New HttpUnauthorizedResult
        End If
    End Sub

    Public Sub New()
        IsRequired = True
    End Sub
End Class
4

2 回答 2

12

我不知道您的主机是谁,但我刚刚在AppHarbor上遇到了类似的问题,并在他们的知识库中发现了这一点:

如果您使用内置的 RequireHttpsAttribute 来确保控制器操作始终使用 HTTPS,您将遇到重定向循环。原因是 SSL 在负载均衡器级别终止,并且 RequireHttps 无法识别它用来指示请求是使用 HTTPS 发出的 X-Forwarded-Proto 标头。因此,您应该为此目的使用自定义 RequireHttps 属性。

他们还在 Github 上提供了一个示例解决方案,为方便起见,我将在下面复制:

using System;
using System.Web.Mvc;
using RequireHttpsAttributeBase = System.Web.Mvc.RequireHttpsAttribute;

namespace AppHarbor.Web
{
    [AttributeUsage(
        AttributeTargets.Class | AttributeTargets.Method,
        Inherited = true,
        AllowMultiple = false)]
    public class RequireHttpsAttribute : RequireHttpsAttributeBase
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (filterContext.HttpContext.Request.IsSecureConnection)
            {
                return;
            }

            if (string.Equals(filterContext.HttpContext.Request.Headers["X-Forwarded-Proto"],
                "https",
                StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }

            if (filterContext.HttpContext.Request.IsLocal)
            {
                return;
            }

            HandleNonHttpsRequest(filterContext);
        }
    }
}

我不确定这是否能解决您的问题;但也许即使您没有使用 AppHarbor,根本原因对您来说也可能是相同的,在这种情况下,上述情况似乎值得一试。

于 2012-06-22T17:20:04.443 回答
0

尝试将其更改为

If Me.IsRequired AndAlso filterContext.HttpContext.Request.Url.Scheme <> "https" Then
    secureUrl = filterContext.HttpContext.Request.Url.OriginalString.Replace("http:", "https:").Remove(filterContext.HttpContext.Request.Url.OriginalString.LastIndexOf(":") + 1)
    filterContext.Result = new RedirectResult(secureUrl)
End If
于 2012-04-12T21:56:50.887 回答