Pivotal CloudFoundry:强制执行 HTTPS (SSL)

Pivotal CloudFoundry: Enforcing HTTPS (SSL)

我想为要托管在 Pivotal CloudFoundry 上的 Spring 启动应用程序强制执行 HTTPS,我想现在大多数应用程序都需要这样做。据我所知,常用的方法是使用

http.requiresChannel().anyRequest().requiresSecure()

但这会导致重定向循环。据我参考 this 之类的 post 的理解,原因是负载均衡器将 https 转换回 http。这意味着,它必须在负载平衡器级别完成。

那么,是否有一些选项可以告诉 CloudFoundry 为应用程序强制执行 HTTPS?如果不是,这不应该是一个功能请求吗?而且,今天有什么好方法可以做到这一点?

更新:来自 Cloud Foundry 或 Spring 安全团队的任何人看到这个 post 了吗?我认为这是在 CloudFoundry 上托管应用程序之前的一项基本功能。谷歌搜索,我没有找到简单的解决方案,只能告诉用户使用 https 而不是 http。但是,即使我这么说,当匿名用户试图访问受限页面时,Spring 安全性会将他重定向回 http 登录页面。

更新 2:当然,我们有许多答案所建议的 x-forwarded-proto header,但我不知道这会有多难自定义 Spring 安全性的功能以使用它。然后,我们还有其他事情,例如 Spring 社交与 Spring 安全集成,我也在那里遇到了一个问题。我认为要么 Spring 安全性和大量其他框架需要提出使用 x-forwarded-proto 的解决方案,要么 CloudFoundry 需要某种方式来透明地处理它。我觉得后者会方便很多。

负载均衡器转发的请求会将名为 x-forwarded-proto 的 http header 设置为 httpshttp。您可以使用它来影响您的应用程序在 SSL 终止方面的行为。

您需要检查 x-forwarded-proto header。这是一种方法。

public boolean isSecure (HttpServletRequest request) {
    String protocol = request.getHeader("x-forwarded-proto");

    if (protocol == null) {
        return false;
    }
    else if (protocol.equals("https")) {
        return true;
    }
    else {
        return false;
    }
}

此外,我还创建了一个示例 servlet 来执行此操作。 https://hub.jazz.net/git/jsloyer/sslcheck

git clone https://hub.jazz.net/git/jsloyer/sslcheck

该应用 运行 上线 http://sslcheck.mybluemix.net and https://sslcheck.mybluemix.net

通常,当您将 WAR 文件推送到 Cloud Foundry 时,Java 构建包会将其部署到 Tomcat。这很好用,因为 Java 构建包可以为您配置 Tomcat 并自动包含一个 RemoteIpValve,它需要 x-forwarded-* headers 并重新配置您的请求 object.

如果您使用 Spring 作为 JAR 文件启动和推送,您将在应用程序中嵌入 Tomcat。因为 Tomcat 嵌入到您的应用程序中,所以 Java 构建包无法为环境配置它(即它无法配置 RemoteIpValve)。这意味着您需要对其进行配置。可以在 here.

中找到使用 Spring Boot 执行此操作的说明

如果您将 Web 应用程序部署为 JAR 文件但使用不同的框架或嵌入式容器,则需要查找您的框架/容器的文档,看看它是否具有自动处理 x-forwarded-* headers。如果没有,您将需要像其他答案建议的那样手动处理它。