Skip to content

Commit 0ccef55

Browse files
eleftheriaskostya05983
authored andcommitted
Allow configuration of session fixation and concurrency through nested builder
Issue: spring-projectsgh-5557
1 parent 817e531 commit 0ccef55

File tree

3 files changed

+95
-4
lines changed

3 files changed

+95
-4
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,11 @@ public SessionManagementConfigurer<HttpSecurity> sessionManagement() throws Exce
681681
* )
682682
* .sessionManagement(sessionManagement ->
683683
* sessionManagement
684-
* .maximumSessions(1)
685-
* .expiredUrl(&quot;/login?expired&quot;)
684+
* .sessionConcurrency(sessionConcurrency ->
685+
* sessionConcurrency
686+
* .maximumSessions(1)
687+
* .expiredUrl(&quot;/login?expired&quot;)
688+
* )
686689
* );
687690
* }
688691
* }

config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.context.event.GenericApplicationListenerAdapter;
2727
import org.springframework.context.event.SmartApplicationListener;
2828
import org.springframework.security.authentication.AuthenticationTrustResolver;
29+
import org.springframework.security.config.Customizer;
2930
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
3031
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
3132
import org.springframework.security.config.http.SessionCreationPolicy;
@@ -249,6 +250,19 @@ public SessionFixationConfigurer sessionFixation() {
249250
return new SessionFixationConfigurer();
250251
}
251252

253+
/**
254+
* Allows configuring session fixation protection.
255+
*
256+
* @param sessionFixationCustomizer the {@link Customizer} to provide more options for
257+
* the {@link SessionFixationConfigurer}
258+
* @return the {@link SessionManagementConfigurer} for further customizations
259+
*/
260+
public SessionManagementConfigurer<H> sessionFixation(Customizer<SessionFixationConfigurer> sessionFixationCustomizer)
261+
throws Exception {
262+
sessionFixationCustomizer.customize(new SessionFixationConfigurer());
263+
return this;
264+
}
265+
252266
/**
253267
* Controls the maximum number of sessions for a user. The default is to allow any
254268
* number of users.
@@ -260,6 +274,20 @@ public ConcurrencyControlConfigurer maximumSessions(int maximumSessions) {
260274
return new ConcurrencyControlConfigurer();
261275
}
262276

277+
/**
278+
* Controls the maximum number of sessions for a user. The default is to allow any
279+
* number of users.
280+
*
281+
* @param sessionConcurrencyCustomizer the {@link Customizer} to provide more options for
282+
* the {@link ConcurrencyControlConfigurer}
283+
* @return the {@link SessionManagementConfigurer} for further customizations
284+
*/
285+
public SessionManagementConfigurer<H> sessionConcurrency(Customizer<ConcurrencyControlConfigurer> sessionConcurrencyCustomizer)
286+
throws Exception {
287+
sessionConcurrencyCustomizer.customize(new ConcurrencyControlConfigurer());
288+
return this;
289+
}
290+
263291
/**
264292
* Invokes {@link #postProcess(Object)} and sets the
265293
* {@link SessionAuthenticationStrategy} for session fixation.
@@ -338,6 +366,18 @@ public SessionManagementConfigurer<H> none() {
338366
*/
339367
public final class ConcurrencyControlConfigurer {
340368

369+
/**
370+
* Controls the maximum number of sessions for a user. The default is to allow any
371+
* number of users.
372+
*
373+
* @param maximumSessions the maximum number of sessions for a user
374+
* @return the {@link ConcurrencyControlConfigurer} for further customizations
375+
*/
376+
public ConcurrencyControlConfigurer maximumSessions(int maximumSessions) {
377+
SessionManagementConfigurer.this.maximumSessions = maximumSessions;
378+
return this;
379+
}
380+
341381
/**
342382
* The URL to redirect to if a user tries to access a resource and their session
343383
* has been expired due to too many sessions for the current user. The default is

config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerTests.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,51 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
202202
}
203203
}
204204

205+
@Test
206+
public void authenticateWhenNewSessionFixationProtectionInLambdaThenCreatesNewSession() throws Exception {
207+
this.spring.register(SFPNewSessionInLambdaConfig.class).autowire();
208+
209+
MockHttpSession givenSession = new MockHttpSession();
210+
String givenSessionId = givenSession.getId();
211+
givenSession.setAttribute("name", "value");
212+
213+
MockHttpSession resultingSession = (MockHttpSession)
214+
this.mvc.perform(get("/auth")
215+
.session(givenSession)
216+
.with(httpBasic("user", "password")))
217+
.andExpect(status().isNotFound())
218+
.andReturn().getRequest().getSession(false);
219+
220+
assertThat(givenSessionId).isNotEqualTo(resultingSession.getId());
221+
assertThat(resultingSession.getAttribute("name")).isNull();
222+
}
223+
224+
@EnableWebSecurity
225+
static class SFPNewSessionInLambdaConfig extends WebSecurityConfigurerAdapter {
226+
@Override
227+
protected void configure(HttpSecurity http) throws Exception {
228+
// @formatter:off
229+
http
230+
.sessionManagement(sessionManagement ->
231+
sessionManagement
232+
.sessionFixation(sessionFixation ->
233+
sessionFixation.newSession()
234+
)
235+
)
236+
.httpBasic(withDefaults());
237+
// @formatter:on
238+
}
239+
240+
@Override
241+
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
242+
// @formatter:off
243+
auth
244+
.inMemoryAuthentication()
245+
.withUser(PasswordEncodedUser.user());
246+
// @formatter:on
247+
}
248+
}
249+
205250
@Test
206251
public void loginWhenUserLoggedInAndMaxSessionsIsOneThenLoginPrevented() throws Exception {
207252
this.spring.register(ConcurrencyControlConfig.class).autowire();
@@ -289,8 +334,11 @@ public void configure(HttpSecurity http) throws Exception {
289334
.formLogin(withDefaults())
290335
.sessionManagement(sessionManagement ->
291336
sessionManagement
292-
.maximumSessions(1)
293-
.maxSessionsPreventsLogin(true)
337+
.sessionConcurrency(sessionConcurrency ->
338+
sessionConcurrency
339+
.maximumSessions(1)
340+
.maxSessionsPreventsLogin(true)
341+
)
294342
);
295343
// @formatter:on
296344
}

0 commit comments

Comments
 (0)