Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security SAML, Redirects going to HTTP instead of HTTPS when using SAMLContextProviderLB set to HTTPs scheme

Attached my context provider for SAMLContextProviderLB bean

**<property name="scheme" value="https"/>**
        <property name="serverName" value="${sp.hostname}"/>
        <property name="serverPort" value="#{'${sp.ssl.port}'=='' ? 443 : '${sp.ssl.port}'}"/>
        <property name="includeServerPortInRequestURL" value="#{'${sp.ssl.port}'=='443' ? false : true }"/>
        <property name="contextPath" value="/${sp.context.root}"/>

I'm behind a reverse Proxy so I'm offloading the SSL Termination. the back-end server itself is listening on non-SSL but the webtier is terminating the SSL for us and forwarding to the non-ssl port. I've set up SAMLContextProviderLB with the above properties so that even tho the backend is https, it will know to map the intended recipient for the saml token as the https audience. What I'm seeing in the logs below however, when I go to a protected resource, its returning garbage on the browser. When I change it to https in the browser, it works as intended. Seeing the logs below shows that the value being return from DefaultSavedRequest url is HTTP when it should be HTTPs.

2016-03-07 18:24:11,907 INFO org.springframework.security.saml.log.SAMLDefaultLogger.log:127 - AuthNResponse;SUCCESS;10.4.203.88;https://myserver:89/fct;https://www.myADFS.com/adfs/services/trust;[email protected];;

2016-03-07 18:24:11,909 DEBUG org.springframework.security.saml.SAMLProcessingFilter.successfulAuthentication:317 - Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.providers.ExpiringUsernameAuthenticationToken@830e9237: Principal: [email protected]; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities

2016-03-07 18:24:11,910 DEBUG org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess:79 - Redirecting to DefaultSavedRequest Url: http://myserver:89/fct/page

2016-03-07 18:24:11,911 DEBUG org.springframework.security.web.DefaultRedirectStrategy.sendRedirect:36 - Redirecting to 'http://myserver:89/fct/page'

2016-03-07 18:24:11,911 DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext:292 - SecurityContext stored to HttpSession: 'org.springframework.security.core.context.SecurityContextImpl@830e9237: Authentication: org.springframework.security.providers.ExpiringUsernameAuthenticationToken@830e9237: Principal: [email protected]; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities'

2016-03-07 18:24:11,912 DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter:97 - SecurityContextHolder now cleared, as request processing completed

Any ideas how to force this to HTTPS under this set up? Thanks in advance.

like image 762
Fernando Avatar asked Mar 07 '16 23:03

Fernando


1 Answers

This question is old but if I found it someone else might so I will post an answer.

Either your load balancer or your Reverse Proxy (Apache httpd or nginx) has to do some extra work for you. Spring (or Spring Boot) and the embedded Tomcat (or Jetty) think they are running an http server. Which it is doing. If the proxy passes some header variables, Tomcat will start to think that it is running https.

Here is what Apache needs as an example:

ProxyPreserveHost On
RequestHeader add X-Forwarded-Proto https
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

ProxyPass and ProxyPassReverse are what you probably already have. But the ProxyPreserveHost and the X-Forwarded-Proto really count.

Check out this section of the Spring Boot Docs. If X-Forwarded-For or X-Forwarded-Proto are set, you need to add this to your application.properties file:

server.use-forward-headers=true

and/or

server.forward-headers-strategy=native

depending on what version of spring boot you use.

You will also see in that document that you can add these properties for Tomcat specific configuration:

server.tomcat.remote-ip-header=x-your-remote-ip-header
server.tomcat.protocol-header=x-your-protocol-header

Do all of this in addition to what you have above and it will start working. What you have above, by itself, is not enough to force Tomcat to start forwarding requests with https.

I found that because my company had a hardware-based load balancer (that is managed by Rackspace), that it was difficult to configure it to make these changes. So we do SSL termination in the firewall/load balancer, then forward the requests to Apache on port 80, and Apache forwards them on to Java on port 8080. Yes, it is a mess. But it got all this nonsense working.

like image 116
sbzoom Avatar answered Sep 20 '22 15:09

sbzoom