Skip to content

Commit 2ea1f06

Browse files
committed
Improved Session Creation Policy Configuration
Other configurers can now offer their preference on session creation policy without trumping what a user provided via the sessionCreationPolicy method. This is valuable for configurer's like Resource Server that would like to have session management be stateless, but not at the expense of the user's direct configuration. Fixes: spring-projectsgh-5518
1 parent 2f1e752 commit 2ea1f06

File tree

2 files changed

+130
-7
lines changed

2 files changed

+130
-7
lines changed

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

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
1818
import java.util.ArrayList;
1919
import java.util.Arrays;
2020
import java.util.List;
21-
2221
import javax.servlet.http.HttpServletResponse;
2322
import javax.servlet.http.HttpSession;
2423

@@ -105,7 +104,7 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
105104
private Integer maximumSessions;
106105
private String expiredUrl;
107106
private boolean maxSessionsPreventsLogin;
108-
private SessionCreationPolicy sessionPolicy = SessionCreationPolicy.IF_REQUIRED;
107+
private SessionCreationPolicy sessionPolicy;
109108
private boolean enableSessionUrlRewriting;
110109
private String invalidSessionUrl;
111110
private String sessionAuthenticationErrorUrl;
@@ -549,7 +548,14 @@ AuthenticationFailureHandler getSessionAuthenticationFailureHandler() {
549548
* @return the {@link SessionCreationPolicy}
550549
*/
551550
SessionCreationPolicy getSessionCreationPolicy() {
552-
return this.sessionPolicy;
551+
if (this.sessionPolicy != null) {
552+
return this.sessionPolicy;
553+
}
554+
555+
SessionCreationPolicy sessionPolicy =
556+
getBuilder().getSharedObject(SessionCreationPolicy.class);
557+
return sessionPolicy == null ?
558+
SessionCreationPolicy.IF_REQUIRED : sessionPolicy;
553559
}
554560

555561
/**
@@ -558,16 +564,18 @@ SessionCreationPolicy getSessionCreationPolicy() {
558564
* @return true if the {@link SessionCreationPolicy} allows session creation
559565
*/
560566
private boolean isAllowSessionCreation() {
561-
return SessionCreationPolicy.ALWAYS == this.sessionPolicy
562-
|| SessionCreationPolicy.IF_REQUIRED == this.sessionPolicy;
567+
SessionCreationPolicy sessionPolicy = getSessionCreationPolicy();
568+
return SessionCreationPolicy.ALWAYS == sessionPolicy
569+
|| SessionCreationPolicy.IF_REQUIRED == sessionPolicy;
563570
}
564571

565572
/**
566573
* Returns true if the {@link SessionCreationPolicy} is stateless
567574
* @return
568575
*/
569576
private boolean isStateless() {
570-
return SessionCreationPolicy.STATELESS == this.sessionPolicy;
577+
SessionCreationPolicy sessionPolicy = getSessionCreationPolicy();
578+
return SessionCreationPolicy.STATELESS == sessionPolicy;
571579
}
572580

573581
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright 2002-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.config.annotation.web.configurers;
18+
19+
import org.junit.Rule;
20+
import org.junit.Test;
21+
22+
import org.springframework.beans.factory.annotation.Autowired;
23+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
24+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
25+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
26+
import org.springframework.security.config.http.SessionCreationPolicy;
27+
import org.springframework.security.config.test.SpringTestRule;
28+
import org.springframework.test.web.servlet.MockMvc;
29+
import org.springframework.test.web.servlet.MvcResult;
30+
import org.springframework.web.bind.annotation.GetMapping;
31+
import org.springframework.web.bind.annotation.RestController;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
35+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
36+
37+
/**
38+
* @author Josh Cummings
39+
*/
40+
public class SessionManagementConfigurerSessionCreationPolicyTests {
41+
@Autowired
42+
MockMvc mvc;
43+
44+
@Rule
45+
public final SpringTestRule spring = new SpringTestRule();
46+
47+
@Test
48+
public void getWhenSharedObjectSessionCreationPolicyConfigurationThenOverrides()
49+
throws Exception {
50+
51+
this.spring.register(StatelessCreateSessionSharedObjectConfig.class).autowire();
52+
53+
MvcResult result = this.mvc.perform(get("/")).andReturn();
54+
55+
assertThat(result.getRequest().getSession(false)).isNull();
56+
}
57+
58+
@EnableWebSecurity
59+
static class StatelessCreateSessionSharedObjectConfig extends WebSecurityConfigurerAdapter {
60+
@Override
61+
protected void configure(HttpSecurity http) throws Exception {
62+
super.configure(http);
63+
http.setSharedObject(SessionCreationPolicy.class, SessionCreationPolicy.STATELESS);
64+
}
65+
}
66+
67+
@Test
68+
public void getWhenUserSessionCreationPolicyConfigurationThenOverrides()
69+
throws Exception {
70+
71+
this.spring.register(StatelessCreateSessionUserConfig.class).autowire();
72+
73+
MvcResult result = this.mvc.perform(get("/")).andReturn();
74+
75+
assertThat(result.getRequest().getSession(false)).isNull();
76+
}
77+
78+
@EnableWebSecurity
79+
static class StatelessCreateSessionUserConfig extends WebSecurityConfigurerAdapter {
80+
@Override
81+
protected void configure(HttpSecurity http) throws Exception {
82+
super.configure(http);
83+
http
84+
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
85+
86+
http.setSharedObject(SessionCreationPolicy.class, SessionCreationPolicy.ALWAYS);
87+
}
88+
}
89+
90+
@Test
91+
public void getWhenDefaultsThenLoginChallengeCreatesSession()
92+
throws Exception {
93+
94+
this.spring.register(DefaultConfig.class, BasicController.class).autowire();
95+
96+
MvcResult result =
97+
this.mvc.perform(get("/"))
98+
.andExpect(status().isUnauthorized())
99+
.andReturn();
100+
101+
assertThat(result.getRequest().getSession(false)).isNotNull();
102+
}
103+
104+
@EnableWebSecurity
105+
static class DefaultConfig extends WebSecurityConfigurerAdapter {
106+
}
107+
108+
@RestController
109+
static class BasicController {
110+
@GetMapping("/")
111+
public String root() {
112+
return "ok";
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)