【问题标题】:Enforcing SSL in service with reverse proxy使用反向代理在服务中强制执行 SSL
【发布时间】:2014-07-09 17:08:33
【问题描述】:

根据Working with SSL in Web API 文章,我实现了一个授权过滤器,要求对 Web API (2.1) 控制器的方法使用 SSL:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true,
                AllowMultiple = false)]
public sealed class RequireHttpsAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                                         {
                                             ReasonPhrase = "HTTPS Required"
                                         };
        }
        else
        {
            base.OnAuthorization(actionContext);
        }
    }
}

这工作正常 - 在某些网络服务器上。如果将 Web Farm Framework (WFF) 用作反向代理,它可能会失败(通过阻止有效的 HTTPS 请求)。

WFF 添加了标头X-Forwarded-Proto,这是反向代理的事实标准。

如何修改此代码以使用或不使用标准代理?

【问题讨论】:

  • 这有点取决于代理,但是当原始请求使用 https 时,大多数代理会添加一些特殊的标头或服务器变量(HTTPSHTTP_HTTPS 变量很流行)。如果您检查您的服务在代理后面的请求中获取的标头和服务器变量,您应该弄清楚。也许这个问题也会有帮助:stackoverflow.com/questions/16330758/….

标签: c# ssl asp.net-web-api reverse-proxy web-farm-framework


【解决方案1】:

这是我想出的:

/// <summary>
/// Action filter to require SSL for a protected resource.
/// </summary>
/// <remarks>
/// From http://www.asp.net/web-api/overview/security/working-with-ssl-in-web-api
/// but modified to support reverse proxies such as Web Farm Framework.
/// </remarks>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class RequireHttpsAttribute : AuthorizationFilterAttribute
{
    [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Not possible.")]
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (IsSecure(actionContext.Request))
        {
            base.OnAuthorization(actionContext);
        }
        else
        {
            actionContext.Response =
                new HttpResponseMessage(HttpStatusCode.Forbidden)
                    {
                        ReasonPhrase = "HTTPS Required"
                    };
        }
    }

    private static bool IsSecure(HttpRequestMessage request)
    {
        if (request.RequestUri.Scheme == Uri.UriSchemeHttps)
        {
            return true;
        }

        IEnumerable<string> headerValues;

        if (request.Headers.TryGetValues("X-Forwarded-Proto", out headerValues))
        {
            string protocol = headerValues.FirstOrDefault();

            return string.Equals(protocol, "https", StringComparison.OrdinalIgnoreCase);
        }

        return false;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 2012-07-20
    • 2021-02-20
    • 2013-05-22
    • 2017-08-25
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多