首页 > 解决方案 > Spring MVC ERR_TOO_MANY_REDIRECTS 错误的 Apache 前端 Tomcat

问题描述

我有一个运行在 Tomcat 服务器(v8.5)上的 Spring MVC(v4.3.1)Web 应用程序,该服务器前面有一个用作反向代理的 Apache(v2.4)应用程序服务器。

我在 Apache 上安装了 SSL 证书,以便它处理所有安全(:443)和非安全(:80)传入请求并将它们重定向到 Tomcat 实例。

我想以安全(SSL)方式处理与外界的所有通信。但是在 Apache 和 Tomcat 之间,没有必要通过安全端口进行通信。这就是 Apache 将所有HTTP请求重定向到HTTPS的原因

我还使用 Spring Security (v4) 来处理所有用户授权/身份验证工作,所以我什至有注册/登录/注销等。

我当前的服务器架构如下所示,

在此处输入图像描述

给出摘要后,问题是,
每当我尝试访问我的登录页面时,我都会从 Chrome 收到ERR_TOO_MANY_REDIRECTS错误。

此外,当我访问 Tomcat 管理器 ( http://myapp.net:8080/manager/html ) 并单击我的应用程序 URL (/MyApp-1.0.0) 然后**我可以成功查看**没有 https 的登录页面. (点击部署在tomcat上的应用链接后,打开页面:http ://myapp.net:8080/MyApp-1.0.0/login )我相信这表明我的web应用在tomcat实例上运行时没有问题. 他们在一起很好。它怀疑我的问题是从带有 SSL 的 Apache 开始的。

虚拟主机的 Apache 配置:

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>

我不想使用重写规则,除非它很关键。我想处理重定向。

Tomcat server.xml 配置:

<Connector   port="8080" protocol="HTTP/1.1"  connectionTimeout="20000" />

没有为:8443定义连接器,因为我不希望 Tomcat 在安全端口上运行。Tomcat 将仅与 Apache 服务器通信。

弹簧安全配置:

@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();
    }

}  

我也读过一些关于 permitAll() 的帖子,anonymous() 是不同的,所以 permitAll() 甚至可能触发一个重定向循环,所以对于登录页面它应该是 anonymous() 但是我无法验证它。我相信它还需要从 spring 安全的角度发挥额外的作用。

我的弹簧控制器:

 @RequestMapping(value = "/", method = RequestMethod.GET)
    public String homePage(Principal principal) {

        /**
         * Initialize session user if not initialized
         */

          return "redirect:/view/home";
    }

其他:

@Controller
@RequestMapping(value = "/view")
public class ViewController
{
 @RequestMapping(value = "/home")
    public String getHomePage(Model model, Principal principal)
    {

        //some logic

        return "home";
    }
}

用于登录的 Web MVC 配置:

@Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");

    }

我有相关的视图解析器视图(home.jsp、login.jsp)

用于重定向的 Chrome 开发者控制台调试输出

 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

请求在这两个从 HTTPS 到 HTTP 和 HTTP 的请求之间再次循环

Apache 访问日志

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 错误日志

[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'

如您所见,我的 spring mvs 应用程序和 tomcat 没有任何与 SSL 相关的代码/配置。他们不需要知道这一点,因为我希望 apache 只负责 SSL 和处理 https 请求并定向到 Tomcat。

我在这里缺少什么,所以我导致了重定向循环?

谢谢

标签: springapachetomcatspring-securityreverse-proxy

解决方案


推荐阅读