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/