mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-25 21:42:17 +00:00
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:
parent
7b25b3e40d
commit
6c541468f6
@ -91,7 +91,8 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>> extends
|
||||
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 InvalidSessionStrategy invalidSessionStrategy;
|
||||
private List<SessionAuthenticationStrategy> sessionAuthenticationStrategies = new ArrayList<SessionAuthenticationStrategy>();
|
||||
@ -475,6 +476,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
return sessionAuthenticationStrategy;
|
||||
}
|
||||
List<SessionAuthenticationStrategy> delegateStrategies = sessionAuthenticationStrategies;
|
||||
if(DEFAULT_SESSION_FIXATION_STRATEGY == sessionFixationAuthenticationStrategy) {
|
||||
sessionFixationAuthenticationStrategy = postProcess(sessionFixationAuthenticationStrategy);
|
||||
}
|
||||
if (isConcurrentSessionControlEnabled()) {
|
||||
SessionRegistry sessionRegistry = getSessionRegistry(http);
|
||||
ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlStrategy = new ConcurrentSessionControlAuthenticationStrategy(
|
||||
|
@ -15,19 +15,19 @@
|
||||
*/
|
||||
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.ObjectPostProcessor
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
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.web.authentication.session.NullAuthenticatedSessionStrategy;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy
|
||||
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.context.SecurityContextPersistenceFilter
|
||||
import org.springframework.security.web.context.SecurityContextRepository
|
||||
import org.springframework.security.web.session.ConcurrentSessionFilter
|
||||
import org.springframework.security.web.session.SessionManagementFilter
|
||||
|
||||
@ -37,124 +37,156 @@ import org.springframework.security.web.session.SessionManagementFilter
|
||||
*/
|
||||
class NamespaceSessionManagementTests extends BaseSpringSpec {
|
||||
|
||||
def "http/session-management"() {
|
||||
when:
|
||||
loadConfig(SessionManagementConfig)
|
||||
then:
|
||||
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy)
|
||||
}
|
||||
def "http/session-management"() {
|
||||
when:
|
||||
loadConfig(SessionManagementConfig)
|
||||
then:
|
||||
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy)
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// enabled by default
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class SessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// enabled by default
|
||||
}
|
||||
}
|
||||
|
||||
def "http/session-management custom"() {
|
||||
setup:
|
||||
CustomSessionManagementConfig.SR = Mock(SessionRegistry)
|
||||
when:
|
||||
loadConfig(CustomSessionManagementConfig)
|
||||
def concurrentStrategy = findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies[0]
|
||||
then:
|
||||
findFilter(SessionManagementFilter).invalidSessionStrategy.destinationUrl == "/invalid-session"
|
||||
findFilter(SessionManagementFilter).failureHandler.defaultFailureUrl == "/session-auth-error"
|
||||
concurrentStrategy.maximumSessions == 1
|
||||
concurrentStrategy.exceptionIfMaximumExceeded
|
||||
concurrentStrategy.sessionRegistry == CustomSessionManagementConfig.SR
|
||||
findFilter(ConcurrentSessionFilter).expiredUrl == "/expired-session"
|
||||
}
|
||||
def "http/session-management custom"() {
|
||||
setup:
|
||||
CustomSessionManagementConfig.SR = Mock(SessionRegistry)
|
||||
when:
|
||||
loadConfig(CustomSessionManagementConfig)
|
||||
def concurrentStrategy = findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies[0]
|
||||
then:
|
||||
findFilter(SessionManagementFilter).invalidSessionStrategy.destinationUrl == "/invalid-session"
|
||||
findFilter(SessionManagementFilter).failureHandler.defaultFailureUrl == "/session-auth-error"
|
||||
concurrentStrategy.maximumSessions == 1
|
||||
concurrentStrategy.exceptionIfMaximumExceeded
|
||||
concurrentStrategy.sessionRegistry == CustomSessionManagementConfig.SR
|
||||
findFilter(ConcurrentSessionFilter).expiredUrl == "/expired-session"
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class CustomSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
static SessionRegistry SR
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.invalidSessionUrl("/invalid-session") // session-management@invalid-session-url
|
||||
.sessionAuthenticationErrorUrl("/session-auth-error") // session-management@session-authentication-error-url
|
||||
.maximumSessions(1) // session-management/concurrency-control@max-sessions
|
||||
.maxSessionsPreventsLogin(true) // session-management/concurrency-control@error-if-maximum-exceeded
|
||||
.expiredUrl("/expired-session") // session-management/concurrency-control@expired-url
|
||||
.sessionRegistry(SR) // session-management/concurrency-control@session-registry-ref
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class CustomSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
static SessionRegistry SR
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.invalidSessionUrl("/invalid-session") // session-management@invalid-session-url
|
||||
.sessionAuthenticationErrorUrl("/session-auth-error") // session-management@session-authentication-error-url
|
||||
.maximumSessions(1) // session-management/concurrency-control@max-sessions
|
||||
.maxSessionsPreventsLogin(true) // session-management/concurrency-control@error-if-maximum-exceeded
|
||||
.expiredUrl("/expired-session") // session-management/concurrency-control@expired-url
|
||||
.sessionRegistry(SR) // session-management/concurrency-control@session-registry-ref
|
||||
}
|
||||
}
|
||||
|
||||
def "http/session-management refs"() {
|
||||
setup:
|
||||
RefsSessionManagementConfig.SAS = Mock(SessionAuthenticationStrategy)
|
||||
when:
|
||||
loadConfig(RefsSessionManagementConfig)
|
||||
then:
|
||||
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it == RefsSessionManagementConfig.SAS }
|
||||
}
|
||||
def "http/session-management refs"() {
|
||||
setup:
|
||||
RefsSessionManagementConfig.SAS = Mock(SessionAuthenticationStrategy)
|
||||
when:
|
||||
loadConfig(RefsSessionManagementConfig)
|
||||
then:
|
||||
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it == RefsSessionManagementConfig.SAS }
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class RefsSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
static SessionAuthenticationStrategy SAS
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionAuthenticationStrategy(SAS) // session-management@session-authentication-strategy-ref
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class RefsSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
static SessionAuthenticationStrategy SAS
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionAuthenticationStrategy(SAS) // session-management@session-authentication-strategy-ref
|
||||
}
|
||||
}
|
||||
|
||||
def "http/session-management@session-fixation-protection=none"() {
|
||||
when:
|
||||
loadConfig(SFPNoneSessionManagementConfig)
|
||||
then:
|
||||
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it instanceof NullAuthenticatedSessionStrategy }
|
||||
}
|
||||
def "http/session-management@session-fixation-protection=none"() {
|
||||
when:
|
||||
loadConfig(SFPNoneSessionManagementConfig)
|
||||
then:
|
||||
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it instanceof NullAuthenticatedSessionStrategy }
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SFPNoneSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy())
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class SFPNoneSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionAuthenticationStrategy(new NullAuthenticatedSessionStrategy())
|
||||
}
|
||||
}
|
||||
|
||||
def "http/session-management@session-fixation-protection=migrateSession (default)"() {
|
||||
when:
|
||||
loadConfig(SFPMigrateSessionManagementConfig)
|
||||
then:
|
||||
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes
|
||||
}
|
||||
def "http/session-management@session-fixation-protection=migrateSession (default)"() {
|
||||
when:
|
||||
loadConfig(SFPMigrateSessionManagementConfig)
|
||||
then:
|
||||
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SFPMigrateSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class SFPMigrateSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
}
|
||||
}
|
||||
|
||||
def "http/session-management@session-fixation-protection=newSession"() {
|
||||
when:
|
||||
loadConfig(SFPNewSessionSessionManagementConfig)
|
||||
then:
|
||||
!findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).migrateSessionAttributes
|
||||
}
|
||||
def "http/session-management@session-fixation-protection=changeSessionId"() {
|
||||
setup:
|
||||
loadConfig(SFPPostProcessedConfig)
|
||||
when:
|
||||
findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).onSessionChange("id", new MockHttpSession(), new TestingAuthenticationToken("u","p","ROLE_USER"))
|
||||
then:
|
||||
context.getBean(MockEventListener).events
|
||||
}
|
||||
|
||||
def findSessionAuthenticationStrategy(def c) {
|
||||
findFilter(SessionManagementFilter).sessionAuthenticationStrategy.delegateStrategies.find { it.class.isAssignableFrom(c) }
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class SFPPostProcessedConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SFPNewSessionSessionManagementConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionFixation()
|
||||
.newSession()
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
public MockEventListener eventListener() {
|
||||
new MockEventListener()
|
||||
}
|
||||
}
|
||||
|
||||
def "http/session-management@session-fixation-protection=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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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.ConcurrentSessionControlAuthenticationStrategy
|
||||
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.SecurityContextPersistenceFilter
|
||||
import org.springframework.security.web.context.SecurityContextRepository
|
||||
@ -48,205 +49,207 @@ import org.springframework.security.web.session.SessionManagementFilter
|
||||
*/
|
||||
class SessionManagementConfigurerTests extends BaseSpringSpec {
|
||||
|
||||
def "sessionManagement does not override explicit RequestCache"() {
|
||||
setup:
|
||||
SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE = Mock(RequestCache)
|
||||
when:
|
||||
loadConfig(SessionManagementDoesNotOverrideExplicitRequestCacheConfig)
|
||||
then:
|
||||
findFilter(ExceptionTranslationFilter).requestCache == SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE
|
||||
}
|
||||
def "sessionManagement does not override explicit RequestCache"() {
|
||||
setup:
|
||||
SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE = Mock(RequestCache)
|
||||
when:
|
||||
loadConfig(SessionManagementDoesNotOverrideExplicitRequestCacheConfig)
|
||||
then:
|
||||
findFilter(ExceptionTranslationFilter).requestCache == SessionManagementDoesNotOverrideExplicitRequestCacheConfig.REQUEST_CACHE
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SessionManagementDoesNotOverrideExplicitRequestCacheConfig extends WebSecurityConfigurerAdapter {
|
||||
static RequestCache REQUEST_CACHE
|
||||
@EnableWebSecurity
|
||||
static class SessionManagementDoesNotOverrideExplicitRequestCacheConfig extends WebSecurityConfigurerAdapter {
|
||||
static RequestCache REQUEST_CACHE
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.requestCache()
|
||||
.requestCache(REQUEST_CACHE)
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
}
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.requestCache()
|
||||
.requestCache(REQUEST_CACHE)
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def "sessionManagement does not override explict SecurityContextRepository"() {
|
||||
setup:
|
||||
SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO = Mock(SecurityContextRepository)
|
||||
when:
|
||||
loadConfig(SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig)
|
||||
then:
|
||||
findFilter(SecurityContextPersistenceFilter).repo == SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO
|
||||
}
|
||||
def "sessionManagement does not override explict SecurityContextRepository"() {
|
||||
setup:
|
||||
SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO = Mock(SecurityContextRepository)
|
||||
when:
|
||||
loadConfig(SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig)
|
||||
then:
|
||||
findFilter(SecurityContextPersistenceFilter).repo == SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter {
|
||||
static SecurityContextRepository SECURITY_CONTEXT_REPO
|
||||
@EnableWebSecurity
|
||||
static class SessionManagementDoesNotOverrideExplicitSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter {
|
||||
static SecurityContextRepository SECURITY_CONTEXT_REPO
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.securityContext()
|
||||
.securityContextRepository(SECURITY_CONTEXT_REPO)
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
}
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.securityContext()
|
||||
.securityContextRepository(SECURITY_CONTEXT_REPO)
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def "invoke sessionManagement twice does not override"() {
|
||||
when:
|
||||
loadConfig(InvokeTwiceDoesNotOverride)
|
||||
then:
|
||||
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
|
||||
}
|
||||
def "invoke sessionManagement twice does not override"() {
|
||||
when:
|
||||
loadConfig(InvokeTwiceDoesNotOverride)
|
||||
then:
|
||||
findFilter(SecurityContextPersistenceFilter).repo.class == NullSecurityContextRepository
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.sessionManagement()
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.sessionManagement()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def 'SEC-2137: disable session fixation and enable concurrency control'() {
|
||||
setup: "context where session fixation is disabled and concurrency control is enabled"
|
||||
loadConfig(DisableSessionFixationEnableConcurrencyControlConfig)
|
||||
String originalSessionId = request.session.id
|
||||
String credentials = "user:password"
|
||||
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
||||
when: "authenticate"
|
||||
springSecurityFilterChain.doFilter(request, response, new MockFilterChain())
|
||||
then: "session invalidate is not called"
|
||||
request.session.id == originalSessionId
|
||||
}
|
||||
def 'SEC-2137: disable session fixation and enable concurrency control'() {
|
||||
setup: "context where session fixation is disabled and concurrency control is enabled"
|
||||
loadConfig(DisableSessionFixationEnableConcurrencyControlConfig)
|
||||
String originalSessionId = request.session.id
|
||||
String credentials = "user:password"
|
||||
request.addHeader("Authorization", "Basic " + credentials.bytes.encodeBase64())
|
||||
when: "authenticate"
|
||||
springSecurityFilterChain.doFilter(request, response, new MockFilterChain())
|
||||
then: "session invalidate is not called"
|
||||
request.session.id == originalSessionId
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class DisableSessionFixationEnableConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
http
|
||||
.httpBasic()
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.sessionFixation().none()
|
||||
.maximumSessions(1)
|
||||
}
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER")
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class DisableSessionFixationEnableConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
http
|
||||
.httpBasic()
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.sessionFixation().none()
|
||||
.maximumSessions(1)
|
||||
}
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER")
|
||||
}
|
||||
}
|
||||
|
||||
def 'session fixation and enable concurrency control'() {
|
||||
setup: "context where session fixation is disabled and concurrency control is enabled"
|
||||
loadConfig(ConcurrencyControlConfig)
|
||||
def authenticatedSession
|
||||
when: "authenticate successfully"
|
||||
request.servletPath = "/login"
|
||||
request.method = "POST"
|
||||
request.setParameter("username", "user");
|
||||
request.setParameter("password","password")
|
||||
springSecurityFilterChain.doFilter(request, response, chain)
|
||||
authenticatedSession = request.session
|
||||
then: "authentication is sucessful"
|
||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||
response.redirectedUrl == "/"
|
||||
when: "authenticate with the same user"
|
||||
super.setup()
|
||||
request.servletPath = "/login"
|
||||
request.method = "POST"
|
||||
request.setParameter("username", "user");
|
||||
request.setParameter("password","password")
|
||||
springSecurityFilterChain.doFilter(request, response, chain)
|
||||
then:
|
||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||
response.redirectedUrl == '/login?error'
|
||||
when: 'SEC-2574: When Session Expires and authentication attempted'
|
||||
context.publishEvent(new HttpSessionDestroyedEvent(authenticatedSession))
|
||||
super.setup()
|
||||
request.servletPath = "/login"
|
||||
request.method = "POST"
|
||||
request.setParameter("username", "user");
|
||||
request.setParameter("password","password")
|
||||
springSecurityFilterChain.doFilter(request, response, chain)
|
||||
then: "authentication is successful"
|
||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||
response.redirectedUrl == "/"
|
||||
}
|
||||
def 'session fixation and enable concurrency control'() {
|
||||
setup: "context where session fixation is disabled and concurrency control is enabled"
|
||||
loadConfig(ConcurrencyControlConfig)
|
||||
def authenticatedSession
|
||||
when: "authenticate successfully"
|
||||
request.servletPath = "/login"
|
||||
request.method = "POST"
|
||||
request.setParameter("username", "user");
|
||||
request.setParameter("password","password")
|
||||
springSecurityFilterChain.doFilter(request, response, chain)
|
||||
authenticatedSession = request.session
|
||||
then: "authentication is sucessful"
|
||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||
response.redirectedUrl == "/"
|
||||
when: "authenticate with the same user"
|
||||
super.setup()
|
||||
request.servletPath = "/login"
|
||||
request.method = "POST"
|
||||
request.setParameter("username", "user");
|
||||
request.setParameter("password","password")
|
||||
springSecurityFilterChain.doFilter(request, response, chain)
|
||||
then:
|
||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||
response.redirectedUrl == '/login?error'
|
||||
when: 'SEC-2574: When Session Expires and authentication attempted'
|
||||
context.publishEvent(new HttpSessionDestroyedEvent(authenticatedSession))
|
||||
super.setup()
|
||||
request.servletPath = "/login"
|
||||
request.method = "POST"
|
||||
request.setParameter("username", "user");
|
||||
request.setParameter("password","password")
|
||||
springSecurityFilterChain.doFilter(request, response, chain)
|
||||
then: "authentication is successful"
|
||||
response.status == HttpServletResponse.SC_MOVED_TEMPORARILY
|
||||
response.redirectedUrl == "/"
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class ConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
http
|
||||
.formLogin()
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.maximumSessions(1)
|
||||
.maxSessionsPreventsLogin(true)
|
||||
}
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER")
|
||||
}
|
||||
}
|
||||
@EnableWebSecurity
|
||||
static class ConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
public void configure(HttpSecurity http) {
|
||||
http
|
||||
.formLogin()
|
||||
.and()
|
||||
.sessionManagement()
|
||||
.maximumSessions(1)
|
||||
.maxSessionsPreventsLogin(true)
|
||||
}
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) {
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER")
|
||||
}
|
||||
}
|
||||
|
||||
def "sessionManagement ObjectPostProcessor"() {
|
||||
setup:
|
||||
AnyObjectPostProcessor opp = Mock()
|
||||
HttpSecurity http = new HttpSecurity(opp, authenticationBldr, [:])
|
||||
when:
|
||||
http
|
||||
.sessionManagement()
|
||||
.maximumSessions(1)
|
||||
.and()
|
||||
.and()
|
||||
.build()
|
||||
def "sessionManagement ObjectPostProcessor"() {
|
||||
setup:
|
||||
AnyObjectPostProcessor opp = Mock()
|
||||
HttpSecurity http = new HttpSecurity(opp, authenticationBldr, [:])
|
||||
when:
|
||||
http
|
||||
.sessionManagement()
|
||||
.maximumSessions(1)
|
||||
.and()
|
||||
.and()
|
||||
.build()
|
||||
|
||||
then: "SessionManagementFilter is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as SessionManagementFilter) >> {SessionManagementFilter o -> o}
|
||||
and: "ConcurrentSessionFilter is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as ConcurrentSessionFilter) >> {ConcurrentSessionFilter o -> o}
|
||||
and: "ConcurrentSessionControlAuthenticationStrategy is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as ConcurrentSessionControlAuthenticationStrategy) >> {ConcurrentSessionControlAuthenticationStrategy o -> o}
|
||||
and: "CompositeSessionAuthenticationStrategy is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as CompositeSessionAuthenticationStrategy) >> {CompositeSessionAuthenticationStrategy o -> o}
|
||||
and: "RegisterSessionAuthenticationStrategy is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as RegisterSessionAuthenticationStrategy) >> {RegisterSessionAuthenticationStrategy o -> o}
|
||||
}
|
||||
then: "SessionManagementFilter is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as SessionManagementFilter) >> {SessionManagementFilter o -> o}
|
||||
and: "ConcurrentSessionFilter is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as ConcurrentSessionFilter) >> {ConcurrentSessionFilter o -> o}
|
||||
and: "ConcurrentSessionControlAuthenticationStrategy is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as ConcurrentSessionControlAuthenticationStrategy) >> {ConcurrentSessionControlAuthenticationStrategy o -> o}
|
||||
and: "CompositeSessionAuthenticationStrategy is registered with ObjectPostProcessor"
|
||||
1 * opp.postProcess(_ as CompositeSessionAuthenticationStrategy) >> {CompositeSessionAuthenticationStrategy o -> o}
|
||||
and: "RegisterSessionAuthenticationStrategy is registered with ObjectPostProcessor"
|
||||
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"() {
|
||||
setup:
|
||||
SharedTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
|
||||
when:
|
||||
loadConfig(SharedTrustResolverConfig)
|
||||
then:
|
||||
findFilter(SecurityContextPersistenceFilter).repo.trustResolver == SharedTrustResolverConfig.TR
|
||||
findFilter(SessionManagementFilter).trustResolver == SharedTrustResolverConfig.TR
|
||||
}
|
||||
def "use sharedObject trustResolver"() {
|
||||
setup:
|
||||
SharedTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
|
||||
when:
|
||||
loadConfig(SharedTrustResolverConfig)
|
||||
then:
|
||||
findFilter(SecurityContextPersistenceFilter).repo.trustResolver == SharedTrustResolverConfig.TR
|
||||
findFilter(SessionManagementFilter).trustResolver == SharedTrustResolverConfig.TR
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
|
||||
static AuthenticationTrustResolver TR
|
||||
@EnableWebSecurity
|
||||
static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
|
||||
static AuthenticationTrustResolver TR
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.setSharedObject(AuthenticationTrustResolver, TR)
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.setSharedObject(AuthenticationTrustResolver, TR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user