3

I want to enforce HTTPS for a Spring Boot application to be hosted at Pivotal CloudFoundry, and I think most of the applications would want this today. The common way of doing it, as I know, is using

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

But this is causing a redirect loop. The cause, as I understand by refering to posts like this, is that the load balancer converts back https to http. That means, it has to be done at the load balancer level.

So, is there some option to tell CloudFoundry to enforce HTTPS for an application? If not, shouldn't this be a feature request? And, what could be a good way to have this today?

Update: Did any of you from Cloud Foundry or Spring Security team see this post? I think this is an essential feature before one can host an application on CloudFoundry. Googling, I found no easy solution but to tell the users to use https instead of http. But, even if I tell so, when an anonymous user tries to access a restricted page, Spring Security is redirecting him back, to the http login page.

Update 2: Of course, we have the x-forwarded-proto header as many answers suggest, but I don't know how hard it would be to customize the features of Spring Security to use that. Then, we have other things like Spring Social integrating with Spring Security, and I just faced an issue there as well. I think either Spring Security and tons of other other frameworks will need to come out with solutions to use x-forwarded-proto, or CloudFoundry needs to have some way to handle it transparently. I think the later would be far convenient.

Community
  • 1
  • 1
Sanjay
  • 8,755
  • 7
  • 46
  • 62

3 Answers3

4

Normally, when you push a WAR file to Cloud Foundry, the Java build pack will take that and deploy it to Tomcat. This works great because the Java build pack can configure Tomcat for you and automatically include a RemoteIpValve, which is what takes the x-forwarded-* headers and reconfigures your request object.

If you're using Spring Boot and pushing as a JAR file, you'll have an embed Tomcat in your application. Because Tomcat is embedded in your app, the Java build pack cannot configure it for the environment (i.e. it cannot configure the RemoteIpValve). This means you need to configure it. Instructions for doing that with Spring Boot can be found here.

If you're deploying an web application as a JAR file but using a different framework or embedded container, you'll need to look up the docs for your framework / container and see if it has automatic handling of the x-forwarded-* headers. If not, you'll need to manually handle that, like the other answers suggest.

Daniel Mikusa
  • 13,716
  • 1
  • 22
  • 28
  • Thanks a lot, Danial! Working perfectly. For Spring Boot users: I just had to add these couple of lines in my application.properties. server.tomcat.remote_ip_header=x-forwarded-for server.tomcat.protocol_header=x-forwarded-proto – Sanjay Feb 06 '15 at 02:29
  • I have elaborated a bit more on this here http://stackoverflow.com/questions/16211878/spring-security-with-https-on-cloudfoundry/34399271#34399271 – Matt C Dec 21 '15 at 15:42
  • Redirect (http to https) does not work with the out of the box tomact provided by java buildpack in bluemix. Is there a provision from bluemix or spring-boot for the same? – Sudheer Sep 29 '16 at 09:24
2

You need to check the x-forwarded-proto header. Here is a method to do this.

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;
    }
}

Additionally, I have created an example servlet that does this as well. https://hub.jazz.net/git/jsloyer/sslcheck

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

The app is running live at http://sslcheck.mybluemix.net and https://sslcheck.mybluemix.net.

Jeff Sloyer
  • 4,899
  • 1
  • 24
  • 48
  • 1
    Thanks, a bit more specific than Scott's answer. But, configuring and customizing Spring Security, handling redirection etc., doesn't look like an easy task to me. Looks like a big hurdle for common coders like me. Like to know if there is some solution already available, or in plan by Spring Security team. – Sanjay Feb 02 '15 at 03:45
  • Could you please update the servlet example not working link https://hub.jazz.net/git/jsloyer/sslcheck – kmarabet Apr 12 '19 at 12:29
0

Requests forwarded by the load balancer will have an http header called x-forwarded-proto set to https or http. You can use this to affect the behavior of your application with regard to SSL termination.

Scott Anderson
  • 1,666
  • 12
  • 12
  • 2
    Thanks, Scott. I had read about this in other posts. But then, I could not find any Spring Security feature to adapt to it. So, I think, one will have to code some custom Spring Security components, which doesn't seem like an easy task to me. Anyone has done that? If either the CloudFoundry guys or the Spring Security guys provide some solution, that would be great. If not, then I guess this could become a big hurdle for Spring applications to be deployed on Cloud foundry. – Sanjay Feb 01 '15 at 13:52