I need to know which users are online on the website and for this reason I’m using the session registry provided by Spring Security (org.springframework.security.core.session.SessionRegistryImpl). Here is my Spring Security configuration:
<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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<beans:bean id="authenticationManager" class="my.package.security.AuthenticationManager" />
<http disable-url-rewriting="true" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/login*" access="ROLE_ANONYMOUS" />
<intercept-url pattern="/*" access="ROLE_USER" />
<form-login login-processing-url="/authorize" login-page="/login" authentication-failure-url="/login-failed" />
<logout logout-url="/logout" logout-success-url="/login" />
<session-management session-authentication-strategy-ref="sas" invalid-session-url="/invalid-session" />
</http>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
</beans:beans>
As you can see, I’m using a custom authentication manager (my.package.security.AuthenticationManager):
public class AuthenticationManager implements org.springframework.security.authentication.AuthenticationManager
{
@Autowired
UserJpaDao userDao;
public Authentication authenticate(Authentication authentication) throws AuthenticationException
{
User loggedInUser = null;
Collection<? extends GrantedAuthority> grantedAuthorities = null;
...
loggedInUser = loggedInUser = userDao.findByAlias(authentication.getName());
if(loggedInUser != null)
{
// Check password etc.
grantedAuthorities = loggedInUser.getAuthorities();
}
else
{
throw new BadCredentialsException("Unknown username");
}
return new UsernamePasswordAuthenticationToken(loggedInUser, authentication.getCredentials(), grantedAuthorities);
}
}
Because of this, sessionRegistry.getAllPrincipals() will return a list of Users (List<Object> “castable” to List<User>). I would like to mantain this because it’s exactly what I need.
Now, the problem is that User is my own class and contains ManyToMany and OneToMany relationships. For this reason, I get a org.hibernate.LazyInitializationException when calling sessionRegistry.getAllPrincipals(). I guess that it happens because this method is not called inside a Transaction, but how can I prevent this exception to happen?
Thank you.
You should not store the user object, but the user id.