У меня есть веб-приложение 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) для обработки всей работы по авторизации / аутентификации пользователей, поэтому у меня даже есть регистрация / вход / выход и т. д.
Моя текущая серверная архитектура показана ниже,
После подведения итогов проблема в том, что
Всякий раз, когда Я пытаюсь получить доступ к своей странице входа в систему, я получаю ошибку 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.
Что мне здесь не хватает, так что я вызываю цикл перенаправления?
Спасибо
Я не уверен, но попробуйте. ProxyPreserveHost Off вместо On. Также проверьте, что у вас есть в вашем файле /etc/hosts для этих двух доменов, которые вы слушаете.
@ EugèneAdell Настройка ProxyPreserveHost On сделала трюк. Но почему так? Итак, я могу получить доступ к странице входа и зарегистрировать пользователя сейчас. Однако, когда пользователь входит в систему, предполагается, что он будет направлять на домашнюю страницу myapp.net/MyApp-1.0.0/view/home. что происходит, он направляется в myapp.net/MyApp-1.0.0/MyApp-1.0.0/view/home, так что он не может его найти. Это работало на моем локальном. Есть идеи, почему это может быть?
Ваш комментарий мне непонятен, извините. Вы говорите, что он перенаправляет на / view / home, что нормально из вашей весенней конфигурации.
Спасибо, Евгений. Позвольте мне попытаться сформулировать это иначе. Проблема в том, что виртуальный хост 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 или что-то подобное? Спасибо
Я нашел ответ здесь: serverfault.com/a/792925/496809
Можете ли вы просмотреть запросы в консоли разработчика в своем браузере и узнать, что это за перенаправления?