3

我尝试使用 spring security xml 中的以下配置访问 CloudFoundry 上的应用程序

<intercept-url pattern="/signup*" access="permitAll" requires-channel="https" />

但它给了我错误这个网页有一个重定向循环

但是,当我将其更改为时,requires-channel="http"我可以正常看到我的页面。在这两种情况下,我都https在我的应用程序中使用了。这是预期的行为吗?

4

3 回答 3

7

首先,退后一步,这(https://johnpfield.wordpress.com/2014/09/10/configuring-ssltls-for-cloud-foundry/)为问题的性质提供了极好的上下文。

关键段落是

“这里的威胁模型是云的入口点是高可用性、安全的代理服务器。一旦流量穿过该边界,它就位于受信任的子网上。事实上,运行 Tomcat 应用程序服务器的实际 IP 地址和端口号在云之外是不可见的。获得对该端口的 HTTP 请求的唯一方法是通过安全代理。这种模式是安全架构从业者中公认的最佳实践。”</p>

因此,我们可能不希望或不需要 SSL,但请继续阅读以了解在使用 Cloud Foundry 上部署的 Spring Security 时如何避免 https 重定向问题。

您将在 Cloud Foundry 安装的边界处拥有负载均衡器、HAProxy 或某种终止 SSL 的代理。作为惯例,无论您使用什么,都应配置为设置 X-Forwarded-For 和 X-Forwarded-Proto 标头。请求标头“X-Forwarded-Proto”包含值 http 或 https,具体取决于原始请求,您需要使用此标头参数在堆栈中进一步做出安全决策。

最干净的方法是在容器级别,因此 Spring Security 的行为与部署容器无关。一些典型的配置选项如下

1) 雄猫

Tomcat 应配置为 RemoteIPValve,如此处所述

好消息是 Cloud Foundry 的 Java buildpack 已经为您完成了这项工作,如此处所示

2)Spring Boot(嵌入式Tomcat)

由于 Tomcat 是嵌入的,Java buildpack 中的 Tomcat 配置不会被激活(参见 buildpack检测标准),因此需要一些内部 Spring Boot 配置。幸运的是,按照您对 Spring Boot 的期望进行配置非常简单,您可以按照此处的说明打开 Tomcat 的 RemoteIPValve ,只需定义

server.tomcat.remote_ip_header=x-forwarded-for

server.tomcat.protocol_header=x-forwarded-proto

这两种方法都会导致 Tomcat 阀覆盖 ServletRequest.isSecure() 行为的相同结果,因此应用程序不知道任何代理的使用。请注意,阀门仅在设置了“X-Forwarded-Proto”标题时使用。

或者,如果你真的想进入低级别,你可以深入研究 Spring Security 的核心,如此处所示。作为这项工作的一部分,关于如何通过 Servlet API 为其他容器(WebLogic、JBoss、Jetty、Glassfish)提供“X-Forwarded-Proto”标头,在https://的评论中分享了一些有用的发现github.com/BroadleafCommerce/BroadleafCommerce/issues/424

作为附加说明,CloudFlare 还可以充当终止 SSL 的反向代理(这是通过此处讨论的 PWS 推荐的方法),它确实转发了相关的标头。

参考

https://stackoverflow.com/a/28300485/752167

http://experts.hybris.com/answers/33612/view.html

https://github.com/cloudfoundry/java-buildpack/commit/540633bc932299ef4335fde16d4069349c66062e

https://support.run.pivotal.io/entries/24898367-Spring-security-with-https

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-use-tomcat-behind-a-proxy-server

于 2015-12-21T15:36:28.507 回答
0

当我尝试使用 Spring Security 使用 HTTPS 保护我的页面时,我遇到了同样的问题。

从 CloudFoundry Support 的讨论来看,他们似乎“在路由器上终止 SSL 连接”。请参阅“是否可以通过 SSL (HTTPS) 访问我的应用程序? ”。

一年多之后,我找不到关于这个问题的更多信息。

于 2013-05-07T17:05:04.020 回答
0

万一它仍然有用......我发现这篇文章提供了解决类似问题的线索。

问题是 org.springframework.security.web.access.channel.SecureChannelProcessor bean 使用 ServletRequest.isSecure() 来决定是接受连接还是重定向,这在云内部变得混乱。

对该 bean 的以下覆盖似乎在 BlueMix 下完成了这项工作 - 不确定 $WSSC 请求标头是否适用于所有环境。

@Component
public class ChannelProcessorsPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
        if (bean instanceof SecureChannelProcessor) {
            final SecureChannelProcessor scp = (SecureChannelProcessor) bean;
            return new ChannelProcessor() {
                @Override
                public void decide(FilterInvocation invocation,
                        Collection<ConfigAttribute> config) throws IOException,
                        ServletException {
                    HttpServletRequest httpRequest = invocation.getHttpRequest();
                    // Running under BlueMix (CloudFoundry in general?), the
                    //   invocation.getHttpRequest().isSecure() in SecureChannelProcessor
                    //   was always returning false
                    if ("https".equals(httpRequest.getHeader("$WSSC"))) {
                        return;
                    }
                    scp.decide(invocation, config);
                }

                @Override
                public boolean supports(ConfigAttribute attribute) {
                    return scp.supports(attribute);
                }
            };
        }

        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {

        return bean;
    }
}
于 2014-06-10T22:30:57.783 回答