HTTPS login with Spring Security redirects to HTTP

SpringSslHttpsSpring SecurityTomcat6

Spring Problem Overview


I have a Spring web app, secured with Spring Security, running on EC2. In front of the EC2 instance is an Elastic Load Balancer with an SSL cert (https terminates at the load balancer ie. port 443 -> port 80), so from Tomcat's perspective, inbound requests are HTTP.

My login form submits to https, however the subsequent redirect goes to http (success or fail). The authentication was successful, and I can go back to https and I'm logged in.

My login configuration looks like so:

<security:form-login
    default-target-url="/home"
    login-page="/"
    login-processing-url="/processlogin"
    authentication-failure-url="/?login_error=1"/>

What do I need to change to make default-target-url and authentication-failure-url go to https?

  • Tomcat 6
  • Spring Security 3.0.x

Spring Solutions


Solution 1 - Spring

Your spring configuration should be agnostic to the used protocol. If you use something like "requires-channel", you'll run into problems sooner or later, especially if you want to deploy the same application to a development environment without https.

Instead, consider to configure your tomcat properly. You can do this with RemoteIpValve. Depending on which headers the loadbalancer sends, your server.xml configuration needs to contain something like this:

<Valve
   className="org.apache.catalina.valves.RemoteIpValve"
   internalProxies=".*"
   protocolHeader="X-Forwarded-Proto"
   httpsServerPort="443"
   />

Spring will determine the absolute redirect address based on the ServletRequest, so change the httpsServerPort if you are using something else than 443:

> The httpsServerPort is the port returned by > ServletRequest.getServerPort() when the protocolHeader indicates https > protocol

Solution 2 - Spring

If it is a Spring Boot application (I use currently the 2.0.0 release), the following configuration within the application.properties file should be enough:

server.tomcat.protocol-header=x-forwarded-proto

This worked for me on AWS with an load balancer at the front.

For Spring Boot < 2.0.0 it should also work (not tested)

Solution 3 - Spring

I had the same problem with Spring Boot behind Google Kubernetes. Adding these two lines to application.properties did it for me

server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto

Source: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https

Solution 4 - Spring

Solution was two fold

(1) application.yml

server:
  use-forward-headers: true

(2) in servers /etc/apache2/sites-enabled/oow.com-le-ssl.conf

RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443

(2.1) and enabled the apache module with

sudo a2enmod headers

Put it together with the help of this and this

Solution 5 - Spring

One way I got this working is by adding the following config

<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint" >
    <form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?login_error=t" always-use-default-target="true" default-target-url="xxxxx" />
    <logout logout-url="/logout" logout-success-url="/logoutSuccess.jsf" />
    ...
</http>

Had to add always-use-default-target="true" and default-target-url="https://....". Not the ideal way as you need to hard code the url in the config.

Solution 6 - Spring

I set requires-channel="any" on all intercept-urls. This allows it to still work in my dev environment where I don't use SSL.

<intercept-url pattern="/createUser" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>

Then, create an apache virtual host that redirects all traffic to the HTTPS version.

<VirtualHost *:80>
  ServerName www.mywebsite.com
  Redirect permanent / https://www.mywebsite.com/
</VirtualHost>

Solution 7 - Spring

I am also facing exactly same problem and till the time I get proper solution I am redirecting my requests from proxy server to tomcat server over AJP instead of HTTP. Below is my apache configuration

ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject

Solution 8 - Spring

use below lines of code in web.xml

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Login and Restricted Space URLs</web-resource-name>
    <url-pattern>/j_security_check</url-pattern>
    <url-pattern>/loginpage.rose</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

it makes forced to use HTTPS.

Solution 9 - Spring

In my case, I had to REMOVE the property server.use-forward-headers=true.

This is my setup:

Digital Ocean LB --> Kubernetes cluster with Ingress --> Spring boot Application

Solution 10 - Spring

Tried everything mentioned above for my k8's to spring boot application, problem was k8 was secured and ssl was handled by SSL accelerator sitting in front of ingress. The application only received http requests and spring security also forwarded to http, which was never found. The solution that worked for me:

nginx.ingress.kubernetes.io/proxy-redirect-from: http://$http_host/ nginx.ingress.kubernetes.io/proxy-redirect-to: https://$http_host/$namespace/helloworld-service/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThodyView Question on Stackoverflow
Solution 1 - SpringmarceljView Answer on Stackoverflow
Solution 2 - SpringRolch2015View Answer on Stackoverflow
Solution 3 - SpringVlad SavelucView Answer on Stackoverflow
Solution 4 - SpringMihkel L.View Answer on Stackoverflow
Solution 5 - SpringSureshView Answer on Stackoverflow
Solution 6 - SpringAndrew Westberg - BCSHView Answer on Stackoverflow
Solution 7 - SpringAgryView Answer on Stackoverflow
Solution 8 - SpringmirzaeiView Answer on Stackoverflow
Solution 9 - SpringCelinHCView Answer on Stackoverflow
Solution 10 - SpringGSMView Answer on Stackoverflow