I have a Spring MVC (v4.3.1) Web application running on a Tomcat server(v8.5) which is fronted by an Apache(v2.4) application server being used as a reverse proxy.
I have SSL certificate installed on Apache so that it handles all secure(:443) and non-secure (:80) incoming requests and redirects them to the Tomcat instance.
I want to handle all communication as secured (SSL) with the outside world. But inside between Apache and Tomcat, it is not necessary to communicate through the secure port. That is why Apache redirects all HTTP requests to HTTPS
I also use Spring Security (v4) to handle all user authorization/authentication work, so I have even Register/Login/Logout, etc.
My current server architecture is shown below,
After giving the summary, the problem is,
Whenever I try to access my login page, I am getting ERR_TOO_MANY_REDIRECTS error from Chrome.
Moreover, when I access Tomcat Manager (http://myapp.net:8080/manager/html) and click on my application URL (/MyApp-1.0.0) then ** I can successfully view** my login page without https. (After clicking the application link deployed on tomcat, it opens page: http://myapp.net:8080/MyApp-1.0.0/login) I believe it shows that there is no problem when my web application is running on tomcat instance. They are good together. It suspects me that my problem starts from Apache with SSL.
Apache configuration for virtual hosts:
Listen 80
Listen 443
<VirtualHost *:80>
ServerAdmin emrecaglar@gmail.com
ServerName myapp.net
ServerAlias www.myapp.net
Redirect / https://www.myapp.net/
</VirtualHost>
<VirtualHost *:443>
ServerName myapp.net
ServerAlias www.myapp.net
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/MyApp-1.0.0/
ProxyPassReverse / http://127.0.0.1:8080/MyApp-1.0.0/
SSLEngine on
SSLCertificateFile /root/WWW.myapp.NET.crt
SSLCertificateKeyFile /root/www.myapp.net.key
SSLCertificateChainFile /root/dv_chain.txt
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
I dont want to use rewrite rules unless it is critical. I want to handle with Redirect.
Tomcat server.xml configuration :
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" />
There is no connector defined for :8443 as I dont want Tomcat to run on a secure port. Tomcat will communicate only with Apache server.
Spring Security configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/static/**").permitAll()
.antMatchers("/register*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.defaultSuccessUrl("/view/home")
.permitAll()
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/login?
logout").invalidateHttpSession(true).deleteCookies("auth_code",
"JSESSIONID").permitAll();
}
}
I have also read some posts about permitAll(), and anonymous() is different, so permitAll() might even trigger a redirect loop so for login page it should be anonymous() however I couldn't validate it. I believe it also needs additional role from spring security perspective.
My Spring Controllers:
@RequestMapping(value = "/", method = RequestMethod.GET)
public String homePage(Principal principal) {
/**
* Initialize session user if not initialized
*/
return "redirect:/view/home";
}
another:
@Controller
@RequestMapping(value = "/view")
public class ViewController
{
@RequestMapping(value = "/home")
public String getHomePage(Model model, Principal principal)
{
//some logic
return "home";
}
}
Web MVC config for login:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
I have related view resolvers and views (home.jsp, login.jsp)
Chrome Developer console debug outputs for redirects
General
Request URL: http://www.myapp.net/MyApp-1.0.0/login
Request Method: GET
Status Code: 302 Found
Remote Address: 207.154.208.158:80
Referrer Policy: no-referrer-when-downgrade
Response Header
HTTP/1.1 302 Found
Date: Sat, 17 Nov 2018 08:40:04 GMT
Server: Apache/2.4.18 (Ubuntu)
Location: https://www.myapp.net/MyApp-1.0.0/login
Content-Length: 314
Keep-Alive: timeout=5, max=92
Connection: Keep-Alive
Request Header
Content-Type: text/html; charset=iso-8859-1
GET /MyApp-1.0.0/login HTTP/1.1
Host: www.myapp.net
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=8A4E001A841DBC4D55509605FF3E7E23
General
Request URL: https://www.myapp.net/MyApp-1.0.0/login
Request Method: GET
Status Code: 302
Remote Address: 207.154.208.158:443
Referrer Policy: no-referrer-when-downgrade
Response Header
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: Keep-Alive
Content-Length: 0
Date: Sat, 17 Nov 2018 08:40:04 GMT
Expires: 0
Keep-Alive: timeout=5, max=92
Location: http://www.myapp.net/MyApp-1.0.0/login
Pragma: no-cache
Server: Apache/2.4.18 (Ubuntu)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Request Header
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Cookie: JSESSIONID=8A4E001A841DBC4D55509605FF3E7E23
Host: www.myapp.net
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36
Requests loop between these two requests from HTTPS to HTTP and HTPPS again
Apache access.log
67.171.8.29 - - [17/Nov/2018:08:41:59 +0000] "GET /MyApp-1.0.0/login HTTP/1.1" 302 429 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36"
Apache error.log
[Sat Nov 17 08:37:59.376633 2018] [mpm_event:notice] [pid 20673:tid 140534533293952] AH00489: Apache/2.4.18 (Ubuntu) mod_jk/1.2.41 OpenSSL/1.0.2g configured -- resuming normal operations
[Sat Nov 17 08:37:59.376707 2018] [core:notice] [pid 20673:tid 140534533293952] AH00094: Command line: '/usr/sbin/apache2'
As you can see, i dont have any SSL related code / config for my spring mvs application and tomcat. They dont need to be aware of that as i want apache be only responsible for SSL and handling https requests and directing to Tomcat.
What i am missing here so that i am causing a redirection loop?
Thanks
