SEC-2913: Post Process default session fixation AuthenticationStrategy

Before the default session fixation AuthenticationStrategy used a
NullEventPublisher when using the Java Configuration. This was due to the
fact that it is not exposed as a Bean and is not post processed.

We now post process the default session fixation AuthenticationStrategy
which initializes the EventPublisher properly.
This commit is contained in:
Rob Winch 2015-03-25 20:54:45 -05:00
parent 7b25b3e40d
commit 6c541468f6
3 changed files with 340 additions and 301 deletions

View File

@ -91,7 +91,8 @@ import org.springframework.util.Assert;
*/ */
public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>> extends public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>> extends
AbstractHttpConfigurer<SessionManagementConfigurer<H>, H> { AbstractHttpConfigurer<SessionManagementConfigurer<H>, H> {
private SessionAuthenticationStrategy sessionFixationAuthenticationStrategy = createDefaultSessionFixationProtectionStrategy(); private final SessionAuthenticationStrategy DEFAULT_SESSION_FIXATION_STRATEGY = createDefaultSessionFixationProtectionStrategy();
private SessionAuthenticationStrategy sessionFixationAuthenticationStrategy = DEFAULT_SESSION_FIXATION_STRATEGY;
private SessionAuthenticationStrategy sessionAuthenticationStrategy; private SessionAuthenticationStrategy sessionAuthenticationStrategy;
private InvalidSessionStrategy invalidSessionStrategy; private InvalidSessionStrategy invalidSessionStrategy;
private List<SessionAuthenticationStrategy> sessionAuthenticationStrategies = new ArrayList<SessionAuthenticationStrategy>(); private List<SessionAuthenticationStrategy> sessionAuthenticationStrategies = new ArrayList<SessionAuthenticationStrategy>();
@ -475,6 +476,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
return sessionAuthenticationStrategy; return sessionAuthenticationStrategy;
} }
List<SessionAuthenticationStrategy> delegateStrategies = sessionAuthenticationStrategies; List<SessionAuthenticationStrategy> delegateStrategies = sessionAuthenticationStrategies;
if(DEFAULT_SESSION_FIXATION_STRATEGY == sessionFixationAuthenticationStrategy) {
sessionFixationAuthenticationStrategy = postProcess(sessionFixationAuthenticationStrategy);
}
if (isConcurrentSessionControlEnabled()) { if (isConcurrentSessionControlEnabled()) {
SessionRegistry sessionRegistry = getSessionRegistry(http); SessionRegistry sessionRegistry = getSessionRegistry(http);
ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlStrategy = new ConcurrentSessionControlAuthenticationStrategy( ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlStrategy = new ConcurrentSessionControlAuthenticationStrategy(

View File

@ -15,19 +15,19 @@
*/ */
package org.springframework.security.config.annotation.web.configurers package org.springframework.security.config.annotation.web.configurers
import org.springframework.context.annotation.Configuration import org.springframework.context.ApplicationListener
import org.springframework.context.annotation.Bean
import org.springframework.mock.web.MockHttpSession
import org.springframework.security.authentication.TestingAuthenticationToken
import org.springframework.security.config.annotation.BaseSpringSpec import org.springframework.security.config.annotation.BaseSpringSpec
import org.springframework.security.config.annotation.ObjectPostProcessor import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry import org.springframework.security.core.session.SessionRegistry
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy
import org.springframework.security.web.authentication.session.SessionFixationProtectionEvent
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy
import org.springframework.security.web.context.SecurityContextPersistenceFilter
import org.springframework.security.web.context.SecurityContextRepository
import org.springframework.security.web.session.ConcurrentSessionFilter import org.springframework.security.web.session.ConcurrentSessionFilter
import org.springframework.security.web.session.SessionManagementFilter import org.springframework.security.web.session.SessionManagementFilter
@ -37,124 +37,156 @@ import org.springframework.security.web.session.SessionManagementFilter
*/ */
class NamespaceSessionManagementTests extends BaseSpringSpec { class NamespaceSessionManagementTests extends BaseSpringSpec {
def "http/session-management"() { def "http/session-management"() {
when: when:
loadConfig(SessionManagementConfig) loadConfig(SessionManagementConfig)
then: then:
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy) findSessionAuthenticationStrategy(SessionFixationProtectionStrategy)
} }
@EnableWebSecurity @EnableWebSecurity
static class SessionManagementConfig extends WebSecurityConfigurerAdapter { static class SessionManagementConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
// enabled by default // enabled by default
} }
} }
def "http/session-management custom"() { def "http/session-management custom"() {
setup: setup:
CustomSessionManagementConfig.SR = Mock(SessionRegistry) CustomSessionManagementConfig.SR = Mock(SessionRegistry)
when: when:
loadConfig(CustomSessionManagementConfig) loadConfig(CustomSessionManagementConfig)
def concurrentStrategy = findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies[0] def concurrentStrategy = findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies[0]
then: then:
findFilter(SessionManagementFilter).invalidSessionStrategy.destinationUrl == "/invalid-session" findFilter(SessionManagementFilter).invalidSessionStrategy.destinationUrl == "/invalid-session"
findFilter(SessionManagementFilter).failureHandler.defaultFailureUrl == "/session-auth-error" findFilter(SessionManagementFilter).failureHandler.defaultFailureUrl == "/session-auth-error"
concurrentStrategy.maximumSessions == 1 concurrentStrategy.maximumSessions == 1
concurrentStrategy.exceptionIfMaximumExceeded concurrentStrategy.exceptionIfMaximumExceeded
concurrentStrategy.sessionRegistry == CustomSessionManagementConfig.SR concurrentStrategy.sessionRegistry == CustomSessionManagementConfig.SR
findFilter(ConcurrentSessionFilter).expiredUrl == "/expired-session" findFilter(ConcurrentSessionFilter).expiredUrl == "/expired-session"
} }
@EnableWebSecurity @EnableWebSecurity
static class CustomSessionManagementConfig extends WebSecurityConfigurerAdapter { static class CustomSessionManagementConfig extends WebSecurityConfigurerAdapter {
static SessionRegistry SR static SessionRegistry SR
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.sessionManagement() .sessionManagement()
.invalidSessionUrl("/invalid-session") // session-management@invalid-session-url .invalidSessionUrl("/invalid-session") // session-management@invalid-session-url
.sessionAuthenticationErrorUrl("/session-auth-error") // session-management@session-authentication-error-url .sessionAuthenticationErrorUrl("/session-auth-error") // session-management@session-authentication-error-url
.maximumSessions(1) // session-management/concurrency-control@max-sessions .maximumSessions(1) // session-management/concurrency-control@max-sessions
.maxSessionsPreventsLogin(true) // session-management/concurrency-control@error-if-maximum-exceeded .maxSessionsPreventsLogin(true) // session-management/concurrency-control@error-if-maximum-exceeded
.expiredUrl("/expired-session") // session-management/concurrency-control@expired-url .expiredUrl("/expired-session") // session-management/concurrency-control@expired-url
.sessionRegistry(SR) // session-management/concurrency-control@session-registry-ref .sessionRegistry(SR) // session-management/concurrency-control@session-registry-ref
} }
} }
def "http/session-management refs"() { def "http/session-management refs"() {
setup: setup:
RefsSessionManagementConfig.SAS = Mock(SessionAuthenticationStrategy) RefsSessionManagementConfig.SAS = Mock(SessionAuthenticationStrategy)
when: when:
loadConfig(RefsSessionManagementConfig) loadConfig(RefsSessionManagementConfig)
then: then:
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it == RefsSessionManagementConfig.SAS } findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it == RefsSessionManagementConfig.SAS }
} }
@EnableWebSecurity @EnableWebSecurity
static class RefsSessionManagementConfig extends WebSecurityConfigurerAdapter { static class RefsSessionManagementConfig extends WebSecurityConfigurerAdapter {
static SessionAuthenticationStrategy SAS static SessionAuthenticationStrategy SAS
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.sessionManagement() .sessionManagement()
.sessionAuthenticationStrategy(SAS) // session-management@session-authentication-strategy-ref .sessionAuthenticationStrategy(SAS) // session-management@session-authentication-strategy-ref
} }
} }
def "http/session-management@session-fixation-protection=none"() { def "http/session-management@session-fixation-protection=none"() {
when: when:
loadConfig(SFPNoneSessionManagementConfig) loadConfig(SFPNoneSessionManagementConfig)
then: then:
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it instanceof NullAuthenticatedSessionStrategy } findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it instanceof NullAuthenticatedSessionStrategy }
} }
@EnableWebSecurity @EnableWebSecurity
static class SFPNoneSessionManagementConfig extends WebSecurityConfigurerAdapter { static class SFPNoneSessionManagementConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.sessionManagement() .sessionManagement()
.sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy()) .sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy())
} }
} }
def "http/session-management@session-fixation-protection=migrateSession (default)"() { def "http/session-management@session-fixation-protection=migrateSession (default)"() {
when: when:
loadConfig(SFPMigrateSessionManagementConfig) loadConfig(SFPMigrateSessionManagementConfig)
then: then:
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes
} }
@EnableWebSecurity @EnableWebSecurity
static class SFPMigrateSessionManagementConfig extends WebSecurityConfigurerAdapter { static class SFPMigrateSessionManagementConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.sessionManagement() .sessionManagement()
} }
} }
def "http/session-management@session-fixation-protection=newSession"() { def "http/session-management@session-fixation-protection=changeSessionId"() {
when: setup:
loadConfig(SFPNewSessionSessionManagementConfig) loadConfig(SFPPostProcessedConfig)
then: when:
!findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).onSessionChange("id", new MockHttpSession(), new TestingAuthenticationToken("u","p","ROLE_USER"))
} then:
context.getBean(MockEventListener).events
}
def findSessionAuthenticationStrategy(def c) { @EnableWebSecurity
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it.class.isAssignableFrom(c) } static class SFPPostProcessedConfig extends WebSecurityConfigurerAdapter {
} @Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
}
@EnableWebSecurity @Bean
static class SFPNewSessionSessionManagementConfig extends WebSecurityConfigurerAdapter { public MockEventListener eventListener() {
@Override new MockEventListener()
protected void configure(HttpSecurity http) throws Exception { }
http }
.sessionManagement()
.sessionFixation() def "http/session-management@session-fixation-protection=newSession"() {
.newSession() when:
} loadConfig(SFPNewSessionSessionManagementConfig)
} then:
!findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes
}
def findSessionAuthenticationStrategy(def c) {
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it.class.isAssignableFrom(c) }
}
@EnableWebSecurity
static class SFPNewSessionSessionManagementConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation()
.newSession()
}
}
static class MockEventListener implements ApplicationListener<SessionFixationProtectionEvent> {
List<SessionFixationProtectionEvent> events = []
public void onApplicationEvent(SessionFixationProtectionEvent event) {
events.add(event)
}
}
} }

View File

@ -34,6 +34,7 @@ import org.springframework.security.web.access.ExceptionTranslationFilter
import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.context.NullSecurityContextRepository import org.springframework.security.web.context.NullSecurityContextRepository
import org.springframework.security.web.context.SecurityContextPersistenceFilter import org.springframework.security.web.context.SecurityContextPersistenceFilter
import org.springframework.security.web.context.SecurityContextRepository import org.springframework.security.web.context.SecurityContextRepository
@ -48,205 +49,207 @@ import org.springframework.security.web.session.SessionManagementFilter
*/ */
class SessionManagementConfigurerTests extends BaseSpringSpec { class SessionManagementConfigurerTests extends BaseSpringSpec {
def "sessionManagement does not override explicit RequestCache"() { def "sessionManagement does not override explicit RequestCache"() {
setup: setup:
SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE = Mock(RequestCache) SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE = Mock(RequestCache)
when: when:
loadConfig(SessionManagementDoesNotOverrideExplicitRequestCacheConfig) loadConfig(SessionManagementDoesNotOverrideExplicitRequestCacheConfig)
then: then:
findFilter(ExceptionTranslationFilter).requestCache == SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE findFilter(ExceptionTranslationFilter).requestCache == SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE
} }
@EnableWebSecurity @EnableWebSecurity
static class SessionManagementDoesNotOverrideExplicitRequestCacheConfig extends WebSecurityConfigurerAdapter { static class SessionManagementDoesNotOverrideExplicitRequestCacheConfig extends WebSecurityConfigurerAdapter {
static RequestCache REQUEST_CACHE static RequestCache REQUEST_CACHE
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.requestCache() .requestCache()
.requestCache(REQUEST_CACHE) .requestCache(REQUEST_CACHE)
.and() .and()
.sessionManagement() .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
} }
} }
def "sessionManagement does not override explict SecurityContextRepository"() { def "sessionManagement does not override explict SecurityContextRepository"() {
setup: setup:
SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO = Mock(SecurityContextRepository) SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO = Mock(SecurityContextRepository)
when: when:
loadConfig(SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig) loadConfig(SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig)
then: then:
findFilter(SecurityContextPersistenceFilter).repo == SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO findFilter(SecurityContextPersistenceFilter).repo == SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO
} }
@EnableWebSecurity @EnableWebSecurity
static class SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter { static class SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter {
static SecurityContextRepository SECURITY_CONTEXT_REPO static SecurityContextRepository SECURITY_CONTEXT_REPO
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.securityContext() .securityContext()
.securityContextRepository(SECURITY_CONTEXT_REPO) .securityContextRepository(SECURITY_CONTEXT_REPO)
.and() .and()
.sessionManagement() .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
} }
} }
def "invoke sessionManagement twice does not override"() { def "invoke sessionManagement twice does not override"() {
when: when:
loadConfig(InvokeTwiceDoesNotOverride) loadConfig(InvokeTwiceDoesNotOverride)
then: then:
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
} }
@EnableWebSecurity @EnableWebSecurity
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter { static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.sessionManagement() .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and() .and()
.sessionManagement() .sessionManagement()
} }
} }
def 'SEC-2137: disable session fixation and enable concurrency control'() { def 'SEC-2137: disable session fixation and enable concurrency control'() {
setup: "context where session fixation is disabled and concurrency control is enabled" setup: "context where session fixation is disabled and concurrency control is enabled"
loadConfig(DisableSessionFixationEnableConcurrencyControlConfig) loadConfig(DisableSessionFixationEnableConcurrencyControlConfig)
String originalSessionId = request.session.id String originalSessionId = request.session.id
String credentials = "user:password" String credentials = "user:password"
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64()) request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
when: "authenticate" when: "authenticate"
springSecurityFilterChain.doFilter(request, response, new MockFilterChain()) springSecurityFilterChain.doFilter(request, response, new MockFilterChain())
then: "session invalidate is not called" then: "session invalidate is not called"
request.session.id == originalSessionId request.session.id == originalSessionId
} }
@EnableWebSecurity @EnableWebSecurity
static class DisableSessionFixationEnableConcurrencyControlConfig extends WebSecurityConfigurerAdapter { static class DisableSessionFixationEnableConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
@Override @Override
public void configure(HttpSecurity http) { public void configure(HttpSecurity http) {
http http
.httpBasic() .httpBasic()
.and() .and()
.sessionManagement() .sessionManagement()
.sessionFixation().none() .sessionFixation().none()
.maximumSessions(1) .maximumSessions(1)
} }
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) { protected void configure(AuthenticationManagerBuilder auth) {
auth auth
.inMemoryAuthentication() .inMemoryAuthentication()
.withUser("user").password("password").roles("USER") .withUser("user").password("password").roles("USER")
} }
} }
def 'session fixation and enable concurrency control'() { def 'session fixation and enable concurrency control'() {
setup: "context where session fixation is disabled and concurrency control is enabled" setup: "context where session fixation is disabled and concurrency control is enabled"
loadConfig(ConcurrencyControlConfig) loadConfig(ConcurrencyControlConfig)
def authenticatedSession def authenticatedSession
when: "authenticate successfully" when: "authenticate successfully"
request.servletPath = "/login" request.servletPath = "/login"
request.method = "POST" request.method = "POST"
request.setParameter("username", "user"); request.setParameter("username", "user");
request.setParameter("password","password") request.setParameter("password","password")
springSecurityFilterChain.doFilter(request, response, chain) springSecurityFilterChain.doFilter(request, response, chain)
authenticatedSession = request.session authenticatedSession = request.session
then: "authentication is sucessful" then: "authentication is sucessful"
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
response.redirectedUrl == "/" response.redirectedUrl == "/"
when: "authenticate with the same user" when: "authenticate with the same user"
super.setup() super.setup()
request.servletPath = "/login" request.servletPath = "/login"
request.method = "POST" request.method = "POST"
request.setParameter("username", "user"); request.setParameter("username", "user");
request.setParameter("password","password") request.setParameter("password","password")
springSecurityFilterChain.doFilter(request, response, chain) springSecurityFilterChain.doFilter(request, response, chain)
then: then:
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
response.redirectedUrl == '/login?error' response.redirectedUrl == '/login?error'
when: 'SEC-2574: When Session Expires and authentication attempted' when: 'SEC-2574: When Session Expires and authentication attempted'
context.publishEvent(new HttpSessionDestroyedEvent(authenticatedSession)) context.publishEvent(new HttpSessionDestroyedEvent(authenticatedSession))
super.setup() super.setup()
request.servletPath = "/login" request.servletPath = "/login"
request.method = "POST" request.method = "POST"
request.setParameter("username", "user"); request.setParameter("username", "user");
request.setParameter("password","password") request.setParameter("password","password")
springSecurityFilterChain.doFilter(request, response, chain) springSecurityFilterChain.doFilter(request, response, chain)
then: "authentication is successful" then: "authentication is successful"
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
response.redirectedUrl == "/" response.redirectedUrl == "/"
} }
@EnableWebSecurity @EnableWebSecurity
static class ConcurrencyControlConfig extends WebSecurityConfigurerAdapter { static class ConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
@Override @Override
public void configure(HttpSecurity http) { public void configure(HttpSecurity http) {
http http
.formLogin() .formLogin()
.and() .and()
.sessionManagement() .sessionManagement()
.maximumSessions(1) .maximumSessions(1)
.maxSessionsPreventsLogin(true) .maxSessionsPreventsLogin(true)
} }
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) { protected void configure(AuthenticationManagerBuilder auth) {
auth auth
.inMemoryAuthentication() .inMemoryAuthentication()
.withUser("user").password("password").roles("USER") .withUser("user").password("password").roles("USER")
} }
} }
def "sessionManagement ObjectPostProcessor"() { def "sessionManagement ObjectPostProcessor"() {
setup: setup:
AnyObjectPostProcessor opp = Mock() AnyObjectPostProcessor opp = Mock()
HttpSecurity http = new HttpSecurity(opp, authenticationBldr, [:]) HttpSecurity http = new HttpSecurity(opp, authenticationBldr, [:])
when: when:
http http
.sessionManagement() .sessionManagement()
.maximumSessions(1) .maximumSessions(1)
.and() .and()
.and() .and()
.build() .build()
then: "SessionManagementFilter is registered with ObjectPostProcessor" then: "SessionManagementFilter is registered with ObjectPostProcessor"
1 * opp.postProcess(_ as SessionManagementFilter) >> {SessionManagementFilter o -> o} 1 * opp.postProcess(_ as SessionManagementFilter) >> {SessionManagementFilter o -> o}
and: "ConcurrentSessionFilter is registered with ObjectPostProcessor" and: "ConcurrentSessionFilter is registered with ObjectPostProcessor"
1 * opp.postProcess(_ as ConcurrentSessionFilter) >> {ConcurrentSessionFilter o -> o} 1 * opp.postProcess(_ as ConcurrentSessionFilter) >> {ConcurrentSessionFilter o -> o}
and: "ConcurrentSessionControlAuthenticationStrategy is registered with ObjectPostProcessor" and: "ConcurrentSessionControlAuthenticationStrategy is registered with ObjectPostProcessor"
1 * opp.postProcess(_ as ConcurrentSessionControlAuthenticationStrategy) >> {ConcurrentSessionControlAuthenticationStrategy o -> o} 1 * opp.postProcess(_ as ConcurrentSessionControlAuthenticationStrategy) >> {ConcurrentSessionControlAuthenticationStrategy o -> o}
and: "CompositeSessionAuthenticationStrategy is registered with ObjectPostProcessor" and: "CompositeSessionAuthenticationStrategy is registered with ObjectPostProcessor"
1 * opp.postProcess(_ as CompositeSessionAuthenticationStrategy) >> {CompositeSessionAuthenticationStrategy o -> o} 1 * opp.postProcess(_ as CompositeSessionAuthenticationStrategy) >> {CompositeSessionAuthenticationStrategy o -> o}
and: "RegisterSessionAuthenticationStrategy is registered with ObjectPostProcessor" and: "RegisterSessionAuthenticationStrategy is registered with ObjectPostProcessor"
1 * opp.postProcess(_ as RegisterSessionAuthenticationStrategy) >> {RegisterSessionAuthenticationStrategy o -> o} 1 * opp.postProcess(_ as RegisterSessionAuthenticationStrategy) >> {RegisterSessionAuthenticationStrategy o -> o}
} and: "SessionFixationProtectionStrategy is registered with ObjectPostProcessor"
1 * opp.postProcess(_ as SessionFixationProtectionStrategy) >> {SessionFixationProtectionStrategy o -> o}
}
def "use sharedObject trustResolver"() { def "use sharedObject trustResolver"() {
setup: setup:
SharedTrustResolverConfig.TR = Mock(AuthenticationTrustResolver) SharedTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
when: when:
loadConfig(SharedTrustResolverConfig) loadConfig(SharedTrustResolverConfig)
then: then:
findFilter(SecurityContextPersistenceFilter).repo.trustResolver == SharedTrustResolverConfig.TR findFilter(SecurityContextPersistenceFilter).repo.trustResolver == SharedTrustResolverConfig.TR
findFilter(SessionManagementFilter).trustResolver == SharedTrustResolverConfig.TR findFilter(SessionManagementFilter).trustResolver == SharedTrustResolverConfig.TR
} }
@EnableWebSecurity @EnableWebSecurity
static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter { static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
static AuthenticationTrustResolver TR static AuthenticationTrustResolver TR
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.setSharedObject(AuthenticationTrustResolver, TR) .setSharedObject(AuthenticationTrustResolver, TR)
} }
} }
} }