[转]HTTPS to HTTP switch

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.

Two ways of fixing this:


RememberMe

Add a remember me entry to your security context:



<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

<security:http auto-config="true">
<security:intercept-url pattern="/login.jsp*"
requires-channel="https" access="IS_AUTHENTICATED_ANONYMOUSLY" />

<security:intercept-url pattern="/j_spring_*"
requires-channel="https" access="IS_AUTHENTICATED_ANONYMOUSLY" />

<security:intercept-url pattern="/**" access="ROLE_USER"
requires-channel="http" />

<security:form-login login-page='/login.jsp' />

<security:port-mappings>
<security:port-mapping http="8081" https="8443" />
</security:port-mappings>

<!-- required for he intercept-url patterns above -->
<security:anonymous />

<!-- required for he logout link in index.jsp -->
<security:logout />

<security:remember-me />
</security:http>

<security:authentication-provider>
<security:user-service>
<security:user password="password" name="chris"
authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>

</beans>


and ensure your login form contains an entry for _spring_security_remember_me:



<input type='hidden' name='_spring_security_remember_me' value="true" />


This will cause Spring to send back another cookie to your browser named SPRING_SECURITY_REMEMBER_ME_COOKIE which doesn't set the secure property, and so you browser will transmit it in either HTTPS or HTTP, and the Spring authentication remember-me bean will be able to 'recover' you previous authentication details


CustomFilter

Another solution is to create a filter which overrides the default Tomcat JSESSIONID behaviour. Note this must appear first in the filter chain:

web.xml



<filter>
<filter-name>httpsCookieFilter</filter-name>
<filter-class>test.HttpsCookieFilter</filter-class>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterPro xy
</filter-class>
</filter>

<!-- Cookie filter must go first to overwrite the default secure property of JSESSIONID -->
<filter-mapping>
<filter-name>httpsCookieFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


and the filter code:



package test;

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;

public class HttpsCookieFilter implements Filter {

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

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

}

 

 

http://static.springsource.org/spring-security/site/faq.html#tomcat-https-session

posted @ 2012-09-28 18:08  杨军  阅读(454)  评论(0)    收藏  举报