Spring Безопасность: require-channel = "https" вызывает цикл перенаправления
У меня возникла проблема с тем, чтобы <security:intercept-url ... requires-channel="https"/>
корректно работать с WAS. Сервер приложений поддерживает SSL.
Когда у меня есть такая конфигурация:
<security:http auto-config="true">
<security:form-login .../>
<security:logout .../>
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<security:intercept-url pattern="/**" access="ROLE_ADMIN,ROLE_USER" />
</security:http>
... Я могу ударить как http://server/myapp
, так и https://server/myapp
. В обоих случаях Spring Security удалось перехватить этот URL-адрес и представить мне страницу входа.
Теперь, что я хочу сделать, нужно перенаправить все URL-адреса http на https-адреса. Итак, я добавил requires-channel="https"
в <security:intercept-url />
<security:http auto-config="true">
<security:form-login .../>
<security:logout .../>
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" requires-channel="https" />
<security:intercept-url pattern="/**" access="ROLE_ADMIN,ROLE_USER" requires-channel="https" />
</security:http>
... теперь, когда я пытаюсь нажать http://server/myapp
, я вижу http://server/myapp/myapp/myapp/myapp/myapp/myapp
, и он переходит в цикл перенаправления.
Итак, я переопределил отображения портов: -
<security:http auto-config="true">
<security:form-login .../>
<security:logout .../>
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" requires-channel="https" />
<security:intercept-url pattern="/**" access="ROLE_ADMIN,ROLE_USER" requires-channel="https" />
<security:port-mappings>
<security:port-mapping http="80" https="443"/>
</security:port-mappings>
</security:http>
... когда я пытаюсь попасть в http://server/myapp
, URL-адрес не изменяется в строке браузера, но я все же получаю проблему с "переходом". Даже если я пытаюсь нажать https://server/myapp
, я все равно получаю ту же проблему.
У меня заканчиваются идеи по отладке этой проблемы. Похоже, что когда я добавляю requires-channel="https"
, он ломается на WAS, но на Jetty он отлично работает. Моим текущим обходным решением является удаление requires-channel="https"
, чтобы https работали над WAS, но затем пользователи могут перейти на сайт с помощью http.
Просто, чтобы выбросить еще одну вещь, добавление порта 9080 для http и порта 9443 для https не устраняет проблему ни на WAS.
Любые идеи? Благодарим вас за помощь.
Ответы
Ответ 1
Моим текущим обходным решением является удаление require-channel = "https", так что https работают на WAS, но затем пользователи могут перейти на сайт с помощью http.
У меня нет решения проблемы, но вот обходной путь, который исправляет это:
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class UnsecureRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (!request.isSecure()) {
response.sendRedirect("https://domain.example.com/");
} else {
filterChain.doFilter(request, response);
}
}
}
Это независимая от платформы платформа, поэтому она должна работать как с WAS, так и с любым другим контейнером.
Ответ 2
У меня была такая же проблема, и я обнаружил, что ответ здесь работает для меня, так как я использовал другой порт по умолчанию для сервера Tomcat. Возможно, необходимо изменить другое сопоставление портов.
https://myshittycode.com/2014/06/12/spring-security-forcing-urls-to-use-https/