Really weird thing going on with JSESSIONID and Spring Security, please advice
Hello everybody,
I'm having a serious issue here and I'm a bit lost.
I've been working on www.zukbox.com with the next security configuration:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<global-method-security pre-post-annotations="enabled">
<!-- AspectJ pointcut expression that locates our "post" method and applies
security that way <protect-pointcut expression="execution(* bigbank.*Service.post*(..))"
access="ROLE_TELLER"/> -->
</global-method-security>
<beans:bean id="authenticationHandler"
class="com.zukbox.zukbox.webapp.filter.ZukboxAuthenticationHandler" />
<http use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint"
auto-config="false">
<intercept-url pattern="/secure/**" access="isAuthenticated()" />
<intercept-url pattern="/payments/book" access="isAuthenticated()" />
<intercept-url pattern="/paypal-checkout" access="isAuthenticated()" />
<intercept-url pattern="/*" access="permitAll" />
<logout />
<remember-me services-ref="rememberMeServices" />
<!-- <session-management session-fixation-protection="none"> -->
<!-- </session-management> -->
<session-management>
<concurrency-control expired-url="/terms" max-sessions="1"/>
</session-management>
<custom-filter position="FORM_LOGIN_FILTER" ref="zukboxAuthenticationFilter" />
</http>
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="userAuthProvider"
class="com.zukbox.zukbox.service.user.impl.UserAuthenticationProviderImpl">
<beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>
<beans:bean id="userDetailsService"
class="com.zukbox.zukbox.service.user.impl.UserDetailsServiceImpl">
<beans:property name="userDao" ref="userDao" />
</beans:bean>
<authentication-manager alias="authManager">
<authentication-provider ref="userAuthProvider"
user-service-ref="userDetailsService">
</authentication-provider>
<authentication-provider ref="facebookAuthenticationProvider"></authentication-provider>
</authentication-manager>
<beans:bean id="rememberMeFilter"
class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
<beans:property name="rememberMeServices" ref="rememberMeServices" />
<beans:property name="authenticationManager" ref="authManager" />
</beans:bean>
<beans:bean id="rememberMeServices"
class="com.zukbox.zukbox.webapp.login.ZukboxRememberMeServices">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="key" value="SpringSecured" />
<beans:property name="alwaysRemember" value="true" />
<beans:property name="tokenValiditySeconds" value="1296000" />
</beans:bean>
<beans:bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<beans:property name="key" value="SpringSecured" />
</beans:bean>
<beans:bean id="facebookAuthenticationProvider"
class="com.zukbox.zukbox.webapp.login.FacebookAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/signin" />
</beans:bean>
<beans:bean id="zukboxAuthenticationFilter"
class="com.zukbox.zukbox.webapp.login.ZukboxAuthenticationFilter">
<beans:property name="authenticationManager" ref="authManager" />
<beans:property name="authenticationFailureHandler"
ref="authenticationHandler" />
<beans:property name="authenticationSuccessHandler"
ref="authenticationHandler" />
<beans:property name="rememberMeServices" ref="rememberMeServices" />
</beans:bean>
<beans:bean id="sessionControlStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<beans:property name="maximumSessions" value="-1" />
</beans:bean>
<beans:bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<beans:property name='securityContextRepository'>
<beans:bean
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<beans:property name='allowSessionCreation' value='false' />
</beans:bean>
</beans:property>
</beans:bean>
</beans:beans>
Code:
FacebookAuthenticationProvider:
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
FacebookAuthenticationToken auth = (FacebookAuthenticationToken) authentication;
FacebookClient fbClient = new DefaultFacebookClient(auth.getToken());
// yada yada yada
AcegiUserDetails details = (AcegiUserDetails) userDetailsService
.loadUserByUsername(user.getEmail());
return new UsernamePasswordAuthenticationToken(details, details.getPassword(),
details.getAuthorities());
}
Code:
public FacebookAuthenticationToken(String socialId, String token, List<GrantedAuthority> authorities) {
super(authorities);
this.socialId = socialId;
this.token = token;
super.setAuthenticated(true);
}
Code:
ZukboxAuthenticationFilter which extends UsernamePasswordAuthenticationFilter
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String loginType = obtainLoginType(request);
AbstractAuthenticationToken authRequest = null;
if ("Facebook".equals(loginType)) {
String socialId = obtainSocialId(request);
String token = obtainToken(request);
authRequest = new FacebookAuthenticationToken(socialId, token);
} else {
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Place the last username attempted into HttpSession for views
HttpSession session = request.getSession(false);
if (session != null || getAllowSessionCreation()) {
request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
}
// Allow subclasses to set the "details" property
setDetails(request, (UsernamePasswordAuthenticationToken) authRequest);
}
return this.getAuthenticationManager().authenticate(authRequest);
}
I'm getting a really short session, sometimes I appear as logged in, sometimes I don't even though the remember me cookie is there.
Same happens with the locale you choose, it jumps to what ever it fits best.
I really don't know where else to look.
Any help/guidance would be much appreciated.
Thanks in advance.
Federico