Фронтинг Tomcat с Apache для Spring Ошибка MVC ERR_TOO_MANY_REDIRECTS

У меня есть веб-приложение Spring MVC (v4.3.1), работающее на сервере Tomcat (v8.5), которое обслуживается сервером приложений Apache (v2.4), который используется в качестве обратного прокси.

У меня установлен сертификат SSL на Apache, чтобы он обрабатывал все безопасные (: 443) и небезопасные (: 80) входящие запросы и перенаправлял их на экземпляр Tomcat.

Я хочу обрабатывать все коммуникации как защищенные (SSL) с внешним миром. Но внутри между Apache и Tomcat нет необходимости связываться через безопасный порт. Вот почему Apache перенаправляет все запросы HTTP на HTTPS

Я также использую Spring Security (v4) для обработки всей работы по авторизации / аутентификации пользователей, поэтому у меня даже есть регистрация / вход / выход и т. д.

Моя текущая серверная архитектура показана ниже,

Фронтинг Tomcat с Apache для Spring Ошибка MVC ERR_TOO_MANY_REDIRECTS

После подведения итогов проблема в том, что
Всякий раз, когда Я пытаюсь получить доступ к своей странице входа в систему, я получаю ошибку ERR_TOO_MANY_REDIRECTS из Chrome.

Кроме того, когда я получаю доступ к Tomcat Manager (http://myapp.net:8080/manager/html) и щелкаю URL-адрес моего приложения (/MyApp-1.0.0), то ** я могу успешно просмотреть ** свою страницу входа без https. (После нажатия на ссылку приложения, развернутую на tomcat, открывается страница: http://myapp.net:8080/MyApp-1.0.0/login) Я считаю, что это показывает, что при запуске моего веб-приложения на экземпляре tomcat проблем нет. Им хорошо вместе. Он подозревает, что моя проблема начинается с Apache с SSL.

Конфигурация Apache для виртуальных хостов:

Listen 80
Listen 443

<VirtualHost *:80>

   ServerAdmin [email protected]
   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>

Я не хочу использовать правила перезаписи, если это не критично. Я хочу справиться с Redirect.

Конфигурация Tomcat server.xml:

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

Для : 8443 не определен соединитель, поскольку я не хочу, чтобы Tomcat работал на защищенном порту. Tomcat будет взаимодействовать только с сервером Apache.

Конфигурация Spring Security:

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

}  

Я также читал несколько сообщений о разрешенииAll (), а anonymous () отличается, поэтому allowAll () может даже вызвать цикл перенаправления, поэтому для страницы входа он должен быть анонимным (), однако я не смог его проверить. Я считаю, что ему также нужна дополнительная роль с точки зрения весенней безопасности.

Мои контроллеры 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 и снова HTPPS

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'

Как видите, у меня нет кода / конфигурации, связанных с SSL, для моего приложения spring mvs и tomcat. Им не нужно знать об этом, поскольку я хочу, чтобы apache отвечал только за SSL и обработку запросов https и перенаправлял их на Tomcat.

Что мне здесь не хватает, так что я вызываю цикл перенаправления?

Спасибо

Можете ли вы просмотреть запросы в консоли разработчика в своем браузере и узнать, что это за перенаправления?

Dusan Bajic 17.11.2018 09:28

Я не уверен, но попробуйте. ProxyPreserveHost Off вместо On. Также проверьте, что у вас есть в вашем файле /etc/hosts для этих двух доменов, которые вы слушаете.

Eugène Adell 17.11.2018 10:25

@ EugèneAdell Настройка ProxyPreserveHost On сделала трюк. Но почему так? Итак, я могу получить доступ к странице входа и зарегистрировать пользователя сейчас. Однако, когда пользователь входит в систему, предполагается, что он будет направлять на домашнюю страницу myapp.net/MyApp-1.0.0/view/home. что происходит, он направляется в myapp.net/MyApp-1.0.0/MyApp-1.0.0/view/home, так что он не может его найти. Это работало на моем локальном. Есть идеи, почему это может быть?

levye 18.11.2018 04:51

Ваш комментарий мне непонятен, извините. Вы говорите, что он перенаправляет на / view / home, что нормально из вашей весенней конфигурации.

Eugène Adell 18.11.2018 08:46

Спасибо, Евгений. Позвольте мне попытаться сформулировать это иначе. Проблема в том, что виртуальный хост Apache повторяет имя контекста Tomcat (в моем случае это MyApp-1.0.0) при перенаправлении его на tomcat. Поэтому вместо /MyApp-1.0.0/view/home он передается как /MyApp-1.0.0/MyApp-1.0.0/view/home. В результате tomcat выдает ошибку, так как такого пути нет. Я не уверен, повторяет ли это Apache контекст Tomcat или сам tomcat. Как вы думаете, следует ли мне изменить конфигурацию ProxyPass на ProxyPass /MyApp-1.0.0 127.0.0.1:8080/MyApp-1.0.0 или что-то подобное? Спасибо

levye 18.11.2018 09:00

Я нашел ответ здесь: serverfault.com/a/792925/496809

levye 18.11.2018 10:24
4
6
1 662
0

Другие вопросы по теме