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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With