Spring Security 3.1.0 - не удается переключиться с HTTPS на HTTP - PullRequest
3 голосов
/ 25 января 2012

Я новичок в Spring Security, поэтому я сделал небольшое веб-приложение, чтобы попробовать его и найти конфигурацию, которая будет полезна для проекта, над которым я работаю. Я принудительно обращаюсь к своей странице входа через HTTPS, и мне нужно вернуться к HTTP после входа в систему. Другими словами:

  • Страница входа: только HTTPS
  • Другие страницы: только HTTP

Я пробовал несколько способов, но я не могу заставить его работать, как я сказал выше. Я прочитал Spring Security FAQ и вижу, что нет «естественного» способа делать то, что я хочу, но меня попросили сделать это, поэтому мне нужен обходной путь, который я не могу найти самостоятельно.

Я использую Spring Security 3.1.0. Мой веб-контейнер - Tomcat 6.0.33.

Это моя конфигурация Spring Security:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:sec="http://www.springframework.org/schema/security"
    xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <sec:http auto-config="true" use-expressions="true">

        <sec:intercept-url pattern="/log*.htm" access="anonymous"
            requires-channel="https" />
        <sec:intercept-url pattern="/admin/**" access="hasRole('admin')"
            requires-channel="http" />
        <sec:intercept-url pattern="/**"
            requires-channel="http" access="hasRole('authenticated')" />

        <sec:form-login login-page="/login.htm"
            default-target-url="/index.htm" authentication-failure-url="/login.htm?error=true"
            always-use-default-target="true" />
        <sec:logout logout-url="/logout.htm" delete-cookies="JSESSIONID" invalidate-session="true" />
        <sec:anonymous/>
        <sec:remember-me use-secure-cookie="true" />
    </sec:http>

    <sec:authentication-manager>
        <sec:authentication-provider>
            <sec:user-service>
                <sec:user name="johnny" password="johnny" authorities="authenticated, admin" />
                <sec:user name="charlie" password="charlie"
                    authorities="authenticated" />
            </sec:user-service>
        </sec:authentication-provider>
    </sec:authentication-manager>

</beans>

Любая помощь будет оценена. Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 07 февраля 2012

Обходной путь, который я нашел для этой проблемы, - отключение защиты фиксации сеанса Spring Security по умолчанию. Мне пришлось добавить элемент «управление сеансом» в конфигурацию XML, которую я впервые описал.

<sec:http auto-config="true">

    <!-- ... -->

    <sec:session-management session-fixation-protection="none"/>

    <!-- ... -->
</sec:http>

В дополнение к этому, URL-адрес, который мы должны предоставить в качестве «URL-адреса приложения», - это не URL-адрес входа в систему, а URL-адрес домашней страницы, например НЕ http://myapp/login.htm НО http://myapp/index.htm. При этом, если пользователь вошел в систему или у него есть cookie-файл запомнить, он сможет войти без проблем и браузер продолжит использовать протокол HTTP. Если нет, пользователь перенаправляется на страницу входа по протоколу HTTPS, и после успешного входа браузер корректно переключается на HTTP. Пожалуйста, примите это во внимание, потому что, если вы напишите (или нажмете) URL-адрес для входа напрямую, HTTPS будет поддерживаться все время.

0 голосов
/ 07 февраля 2012

Это возможно, добавив фильтр в цепочку фильтров, который изменяет ваш файл cookie

В вашем конфигурационном файле создайте фильтр и добавьте его в цепочку фильтров следующим образом:

<bean name="httpsCookieFilter" class="bla.bla.bla.HttpsCookieFilter"/>

<security:http auto-config="false" entry-point-ref="authenticationEntryPoint">
...
    <security:custom-filter position="FIRST" ref="httpsCookieFilter" />
...
</security:http>

И ваш код фильтра выглядит примерно так

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Sessions created under HTTPS, for which the session cookie is marked as “secure”, cannot subsequently be used under 
 * HTTP. The browser will not send the cookie back to the server and any session state will be lost (including the
 * security context information)
 *
 * Tomcat tracks user sessions with the help of the JSESSIONID cookie. If you enter into HTTPS with Tomcat, the cookie
 * will come back with the secure property being set to true. Subsequently when the redirection to http occurs, the
 * browser will not transmit the JSESSIONID cookie and you'll get a new session.
 *
 * This filter overrides the default Tomcat JSESSIONID behaviour
 */
public class HttpsCookieFilter implements Filter {

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        final HttpServletRequest httpRequest = (HttpServletRequest) request;
        final HttpServletResponse httpResponse = (HttpServletResponse) response;
        final HttpSession session = httpRequest.getSession(false);

        if (session != null) {
            final Cookie sessionCookie = new Cookie("JSESSIONID", session.getId());
            sessionCookie.setMaxAge(-1);
            sessionCookie.setSecure(false);
            sessionCookie.setPath(httpRequest.getContextPath());
            httpResponse.addCookie(sessionCookie);
        }

        chain.doFilter(request, response);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...