Вход в систему HTTPS с помощью Spring Переадресация безопасности на HTTP
У меня есть веб-приложение Spring, защищенное Spring Безопасность, работающее на EC2. Перед экземпляром EC2 есть балансировщик эластичной нагрузки с сертификатом SSL (https завершается на балансировщике нагрузки, то есть порт 443 → порт 80), поэтому с точки зрения Tomcat входящие запросы являются HTTP.
Моя форма входа отправляется в https, однако последующая переадресация переходит на http (успех или сбой). Аутентификация прошла успешно, и я могу вернуться к https, и я вошел в систему.
Моя конфигурация входа выглядит так:
<security:form-login
default-target-url="/home"
login-page="/"
login-processing-url="/processlogin"
authentication-failure-url="/?login_error=1"/>
Что мне нужно изменить, чтобы сделать URL-адрес-url-url и аутентификацию-отказ-url перейти на https?
- Tomcat 6
- Spring Безопасность 3.0.x
Ответы
Ответ 1
Конфигурация spring должна быть агностикой для используемого протокола. Если вы используете что-то вроде "require-channel", рано или поздно вы столкнетесь с проблемами, особенно если вы хотите развернуть одно и то же приложение в среде разработки без https.
Вместо этого подумайте о том, чтобы правильно настроить ваш tomcat. Вы можете сделать это с помощью RemoteIpValve. В зависимости от того, какие заголовки посылает loadbalancer, ваша конфигурация server.xml должна содержать что-то вроде этого:
<Valve
className="org.apache.catalina.valves.RemoteIpValve"
internalProxies=".*"
protocolHeader="X-Forwarded-Proto"
httpsServerPort="443"
/>
Spring будет определять абсолютный адрес перенаправления на основе ServletRequest, поэтому измените httpsServerPort, если вы используете что-то еще, чем 443:
httpsServerPort - это порт, возвращаемый ServletRequest.getServerPort(), когда протоколHeader указывает https Протокол
Ответ 2
Один из способов получить эту работу - добавить следующую конфигурацию
<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint" >
<form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?login_error=t" always-use-default-target="true" default-target-url="xxxxx" />
<logout logout-url="/logout" logout-success-url="/logoutSuccess.jsf" />
...
</http>
Пришлось добавить always-use-default-target="true"
и default-target-url="https://...."
. Не идеальный способ, так как вам нужно жестко закодировать URL-адрес в конфиге.
Ответ 3
Если это приложение Spring Boot (в настоящее время я использую версию 2.0.0), то в файле application.properties
должно быть достаточно следующей конфигурации:
server.tomcat.protocol-header=x-forwarded-proto
Это сработало для меня на AWS с балансировщиком нагрузки спереди.
Для Spring Boot <2.0.0 он также должен работать (не тестировался)
Ответ 4
Я устанавливаю require-channel = "any" на все перехватывающие URL-адреса. Это позволяет ему по-прежнему работать в моей среде dev, где я не использую SSL.
<intercept-url pattern="/createUser" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
Затем создайте виртуальный хост apache, который перенаправляет весь трафик на версию HTTPS.
<VirtualHost *:80>
ServerName www.mywebsite.com
Redirect permanent / https://www.mywebsite.com/
</VirtualHost>
Ответ 5
Я также сталкиваюсь с точно такой же проблемой, и до момента получения правильного решения я перенаправляю свои запросы с прокси-сервера на сервер tomcat через AJP вместо HTTP.
Ниже приведена конфигурация apache
ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject
Ответ 6
используйте строки кода в web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Login and Restricted Space URLs</web-resource-name>
<url-pattern>/j_security_check</url-pattern>
<url-pattern>/loginpage.rose</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
он вынужден использовать HTTPS.
Ответ 7
У меня была такая же проблема с Spring Boot за Google Kubernetes. Добавление этих двух строк в application.properties сделало это для меня
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
Источник: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https