Spring Security originally redirected on authentication success with an absolute URL, conforming to https://www.rfc-editor.org/rfc/rfc2616#section-14.30. More broadly, any redirects to within the application should use relative URL
However, this RFC is now obsolete. To that end, the reactive stack redirects using a relative URL. It would be good to bring the servlet code into alignment.
Comment From: davidcostanzo
I was going to open an issue "HttpSecurity.formLogin() ignores server.tomcat.use-relative-redirects=true" but that might be a duplicate of this issue. I don't understand enough of Spring internals to be sure. Are they the same?
Is there a way for an application to force the login redirection to use relative URLs, even if the framework doesn't do it automatically or if it doesn't work in all cases?
Impact:
My application has a problem where HttpSecurity.formLogin() ignores the server.tomcat.use-relative-redirects=true property. My application sometimes sits behind a reverse proxy that acts as a TLS endpoint. In this scenario when people use my application through the proxy with HTTPS, all of my application's redirects are relative and thus continue to use HTTPS except for the login page. The impact is that people end up transmitting their credentials unencrypted even though they thought they were using HTTPS.
Comment From: davidcostanzo
When I posted my earlier comment, I was completely lost. The proposed fix for this issue put me on a path to understanding the control flow. I think the absolute URL is created in LoginUrlAuthenticationEntryPoint. buildRedirectUrlToLoginPage(), which goes out of its way to convert a relative URL to an absolute one, conforming to the obsolete RFC.
I was able to work around this problem in my application by creating a subclass of LoginUrlAuthenticationEntryPoint that overrides buildRedirectUrlToLoginPage to return the URL that determineUrlToUseForThisRequest returns, which is a relative URL in my case. In my application's SecurityFilterChain bean, it additionally configures the HttpSecurity with
http.exceptionHandling(exceptionHandling -> {
exceptionHandling.authenticationEntryPoint(new MyLoginUrlAuthenticationEntryPoint("/login"));
});
This ignores any port mapper configuration, so it won't work for everyone.
Comment From: jzheaux
Note that I removed the breaks-passivity label by putting this behind a setting, setFavorRedirectUris. This default will get switched in Spring Security 7.