mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 01:02:14 +00:00
Allow configuration of session fixation and concurrency through nested builder
Issue: gh-5557
This commit is contained in:
parent
4b2539df10
commit
7961b819aa
@ -681,8 +681,11 @@ public final class HttpSecurity extends
|
|||||||
* )
|
* )
|
||||||
* .sessionManagement(sessionManagement ->
|
* .sessionManagement(sessionManagement ->
|
||||||
* sessionManagement
|
* sessionManagement
|
||||||
* .maximumSessions(1)
|
* .sessionConcurrency(sessionConcurrency ->
|
||||||
* .expiredUrl("/login?expired")
|
* sessionConcurrency
|
||||||
|
* .maximumSessions(1)
|
||||||
|
* .expiredUrl("/login?expired")
|
||||||
|
* )
|
||||||
* );
|
* );
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
@ -26,6 +26,7 @@ import org.springframework.context.ApplicationListener;
|
|||||||
import org.springframework.context.event.GenericApplicationListenerAdapter;
|
import org.springframework.context.event.GenericApplicationListenerAdapter;
|
||||||
import org.springframework.context.event.SmartApplicationListener;
|
import org.springframework.context.event.SmartApplicationListener;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
@ -249,6 +250,19 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
return new SessionFixationConfigurer();
|
return new SessionFixationConfigurer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows configuring session fixation protection.
|
||||||
|
*
|
||||||
|
* @param sessionFixationCustomizer the {@link Customizer} to provide more options for
|
||||||
|
* the {@link SessionFixationConfigurer}
|
||||||
|
* @return the {@link SessionManagementConfigurer} for further customizations
|
||||||
|
*/
|
||||||
|
public SessionManagementConfigurer<H> sessionFixation(Customizer<SessionFixationConfigurer> sessionFixationCustomizer)
|
||||||
|
throws Exception {
|
||||||
|
sessionFixationCustomizer.customize(new SessionFixationConfigurer());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the maximum number of sessions for a user. The default is to allow any
|
* Controls the maximum number of sessions for a user. The default is to allow any
|
||||||
* number of users.
|
* number of users.
|
||||||
@ -260,6 +274,20 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
return new ConcurrencyControlConfigurer();
|
return new ConcurrencyControlConfigurer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the maximum number of sessions for a user. The default is to allow any
|
||||||
|
* number of users.
|
||||||
|
*
|
||||||
|
* @param sessionConcurrencyCustomizer the {@link Customizer} to provide more options for
|
||||||
|
* the {@link ConcurrencyControlConfigurer}
|
||||||
|
* @return the {@link SessionManagementConfigurer} for further customizations
|
||||||
|
*/
|
||||||
|
public SessionManagementConfigurer<H> sessionConcurrency(Customizer<ConcurrencyControlConfigurer> sessionConcurrencyCustomizer)
|
||||||
|
throws Exception {
|
||||||
|
sessionConcurrencyCustomizer.customize(new ConcurrencyControlConfigurer());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes {@link #postProcess(Object)} and sets the
|
* Invokes {@link #postProcess(Object)} and sets the
|
||||||
* {@link SessionAuthenticationStrategy} for session fixation.
|
* {@link SessionAuthenticationStrategy} for session fixation.
|
||||||
@ -338,6 +366,18 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
*/
|
*/
|
||||||
public final class ConcurrencyControlConfigurer {
|
public final class ConcurrencyControlConfigurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the maximum number of sessions for a user. The default is to allow any
|
||||||
|
* number of users.
|
||||||
|
*
|
||||||
|
* @param maximumSessions the maximum number of sessions for a user
|
||||||
|
* @return the {@link ConcurrencyControlConfigurer} for further customizations
|
||||||
|
*/
|
||||||
|
public ConcurrencyControlConfigurer maximumSessions(int maximumSessions) {
|
||||||
|
SessionManagementConfigurer.this.maximumSessions = maximumSessions;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL to redirect to if a user tries to access a resource and their session
|
* The URL to redirect to if a user tries to access a resource and their session
|
||||||
* has been expired due to too many sessions for the current user. The default is
|
* has been expired due to too many sessions for the current user. The default is
|
||||||
|
@ -202,6 +202,51 @@ public class SessionManagementConfigurerTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authenticateWhenNewSessionFixationProtectionInLambdaThenCreatesNewSession() throws Exception {
|
||||||
|
this.spring.register(SFPNewSessionInLambdaConfig.class).autowire();
|
||||||
|
|
||||||
|
MockHttpSession givenSession = new MockHttpSession();
|
||||||
|
String givenSessionId = givenSession.getId();
|
||||||
|
givenSession.setAttribute("name", "value");
|
||||||
|
|
||||||
|
MockHttpSession resultingSession = (MockHttpSession)
|
||||||
|
this.mvc.perform(get("/auth")
|
||||||
|
.session(givenSession)
|
||||||
|
.with(httpBasic("user", "password")))
|
||||||
|
.andExpect(status().isNotFound())
|
||||||
|
.andReturn().getRequest().getSession(false);
|
||||||
|
|
||||||
|
assertThat(givenSessionId).isNotEqualTo(resultingSession.getId());
|
||||||
|
assertThat(resultingSession.getAttribute("name")).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class SFPNewSessionInLambdaConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.sessionManagement(sessionManagement ->
|
||||||
|
sessionManagement
|
||||||
|
.sessionFixation(sessionFixation ->
|
||||||
|
sessionFixation.newSession()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.httpBasic(withDefaults());
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
auth
|
||||||
|
.inMemoryAuthentication()
|
||||||
|
.withUser(PasswordEncodedUser.user());
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loginWhenUserLoggedInAndMaxSessionsIsOneThenLoginPrevented() throws Exception {
|
public void loginWhenUserLoggedInAndMaxSessionsIsOneThenLoginPrevented() throws Exception {
|
||||||
this.spring.register(ConcurrencyControlConfig.class).autowire();
|
this.spring.register(ConcurrencyControlConfig.class).autowire();
|
||||||
@ -289,8 +334,11 @@ public class SessionManagementConfigurerTests {
|
|||||||
.formLogin(withDefaults())
|
.formLogin(withDefaults())
|
||||||
.sessionManagement(sessionManagement ->
|
.sessionManagement(sessionManagement ->
|
||||||
sessionManagement
|
sessionManagement
|
||||||
.maximumSessions(1)
|
.sessionConcurrency(sessionConcurrency ->
|
||||||
.maxSessionsPreventsLogin(true)
|
sessionConcurrency
|
||||||
|
.maximumSessions(1)
|
||||||
|
.maxSessionsPreventsLogin(true)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user