2012-01-25 2 views
3

Я новичок в Spring Security, поэтому я сделал небольшой webapp, чтобы попробовать его и найти конфигурацию, которая будет полезна для проекта, над которым я работаю. Я принуждая мою страницу входа в систему, чтобы получить доступ через HTTPS, и мне нужно, чтобы вернуться к HTTP после входа в систему Другими словами.Spring Security 3.1.0 - Невозможно переключиться с 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> 

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

+3

Считается, что это не рекомендуется; он позволяет украсть сессионный файл cookie, стиль Firesheep. –

+0

Да, я знаю, что это не правильное решение, но я также думаю, что это зависит от типа приложения, которое вы строите, и от нагрузки на сервер, которую вы допустили бы. К сожалению, в этом случае меня попросили сделать это по некоторым (темным) причинам. В любом случае, спасибо за ваш комментарий, мы не должны забывать, что этот подход весьма уязвим. – nomusicnolife

ответ

0

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

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

<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); 
    } 

} 
+0

Благодарим вас за ответ. Во всяком случае, почему-то этот подход фильтра не работает для меня. Тем временем я нашел другой способ заставить его работать, что я объясню в отдельном ответе. Я думаю, что оба подхода должны быть опробованы любым разработчиком, у которого может быть такая же проблема. – nomusicnolife

1

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

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

    <!-- ... --> 

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

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

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

Смежные вопросы