Yeah I agree, I suck at titles :) But, again and again, Spring guys are real badasses :)
By default, Spring Security keeps the SecurityContext
object in session objects of user between requests. SecurityContextPersistenceFilter
manages this task. When a request comes, it reads the SecurityContext
object from a security context repository (which I will mention in a second), puts it to SecurityContextHolder
to be used by other filters and the application. And when request is completed, it clears the SecurityContextHolder
and puts the SecurityContext
to the repository. The repository I mentioned here is the HttpSessionSecurityContextRepository
class which is an implementation of SecurityContextRepository
interface. This interface is responsible for persisting SecurityContext
objects between requests and used by SecurityContextPersistenceFilter
.
For a requirement we get, we need to read the logged in user information from memcached, not the http session. With a little investigation, we saw the SecurityContextRepository
interface and its default HttpSessionSecurityContextRepository
implementation. We figured out that with a custom implementation of that interface, Spring Security will still work quite well for our situation. So we coded our implementation and tried to inject it into the SpringSecurityContextPersistenceFilter
.
Configuring Spring Security to use the custom repository was a more challenging task than writing a custom implementation for us because we could not see a point for the configuration :) In the reference documentation, the bean definition below is given:
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name='securityContextRepository'>
<bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='false' />
</bean>
</property>
</bean>
And this explanation is given: > Alternatively you could provide a null implementation of the SecurityContextRepository interface, which will prevent the security context from being stored, even if a session has already been created during the request. (Section 8.3)
So we copied the bean definition above and replaced the default repository with ours.
When we started the application, we traced the logs and saw that Spring Security was still using the default http session repository instead of our repository.
After a little bit more investigation, we understood that we had to use the security-context-repository-ref
attribute of http namespace
in configuration. Although a SecurityPersistenceContextFilter
bean definition is provided, when http namespace
is used, Spring Security creates its own SecurityPersistenceContextFilter
with defaults. So to customize it, security-context-repository
attribute must be used.
So here is the appropriate configuration:
<sec:http auto-config="false" security-context-repository-ref="memcachedSecurityContextRepository">
<!-- ... -->
</sec:http>
<bean id="memcachedSecurityContextRepository" class="...MemcachedSecurityContextRepository" />
We could not understand why Section 8.3 of the Spring Security reference does not state this.
I also wrote a similar post on a related question on Stackoverflow which you can have a look with this link: http://stackoverflow.com/questions/2504590/how-can-i-use-spring-security-without-sessions/7653699#7653699
Also javadocs are quite useful: http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/context/SecurityContextPersistenceFilter.html http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/context/SecurityContextRepository.html