Skip to content

Commit 1e7f25c

Browse files
committed
Add createdTime field to SessionInformation
Closes: gh-17359 Signed-off-by: Andrey Litvitski <andrey1010102008@gmail.com>
1 parent 5fefdd5 commit 1e7f25c

File tree

10 files changed

+40
-19
lines changed

10 files changed

+40
-19
lines changed

config/src/test/java/org/springframework/security/SerializationSamples.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ final class SerializationSamples {
256256
generatorByClassName.put(OAuth2AuthorizationExchange.class, (r) -> TestOAuth2AuthorizationExchanges.success());
257257
generatorByClassName.put(OidcUserInfo.class, (r) -> OidcUserInfo.builder().email("email@example.com").build());
258258
generatorByClassName.put(SessionInformation.class,
259-
(r) -> new SessionInformation(user, r.alphanumeric(4), new Date(1704378933936L)));
259+
(r) -> new SessionInformation(user, r.alphanumeric(4), new Date(1704378933936L), new Date()));
260260
generatorByClassName.put(ReactiveSessionInformation.class,
261261
(r) -> new ReactiveSessionInformation(user, r.alphanumeric(4), Instant.ofEpochMilli(1704378933936L)));
262262
generatorByClassName.put(OAuth2AccessToken.class, (r) -> TestOAuth2AccessTokens.scopes("scope"));

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ public void authenticateWhenUsingInvalidSessionUrlThenMatchesNamespace() throws
111111
public void authenticateWhenUsingExpiredUrlThenMatchesNamespace() throws Exception {
112112
this.spring.register(CustomSessionManagementConfig.class).autowire();
113113
MockHttpSession session = new MockHttpSession();
114-
SessionInformation sessionInformation = new SessionInformation(new Object(), session.getId(), new Date(0));
114+
SessionInformation sessionInformation = new SessionInformation(new Object(), session.getId(), new Date(0),
115+
new Date());
115116
sessionInformation.expireNow();
116117
SessionRegistry sessionRegistry = this.spring.getContext().getBean(SessionRegistry.class);
117118
given(sessionRegistry.getSessionInformation(session.getId())).willReturn(sessionInformation);

config/src/test/kotlin/org/springframework/security/config/annotation/web/session/SessionConcurrencyDslTests.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class SessionConcurrencyDslTests {
101101
mockkObject(ExpiredUrlConfig.SESSION_REGISTRY)
102102

103103
val session = MockHttpSession()
104-
val sessionInformation = SessionInformation("", session.id, Date(0))
104+
val sessionInformation = SessionInformation("", session.id, Date(0), Date())
105105
sessionInformation.expireNow()
106106
every { ExpiredUrlConfig.SESSION_REGISTRY.getSessionInformation(any()) } returns sessionInformation
107107

@@ -141,7 +141,7 @@ class SessionConcurrencyDslTests {
141141
mockkObject(ExpiredSessionStrategyConfig.SESSION_REGISTRY)
142142

143143
val session = MockHttpSession()
144-
val sessionInformation = SessionInformation("", session.id, Date(0))
144+
val sessionInformation = SessionInformation("", session.id, Date(0), Date())
145145
sessionInformation.expireNow()
146146
every { ExpiredSessionStrategyConfig.SESSION_REGISTRY.getSessionInformation(any()) } returns sessionInformation
147147

core/src/main/java/org/springframework/security/core/session/SessionInformation.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
* <code>Filter</code>.
3737
*
3838
* @author Ben Alex
39+
* @author Andrey Litvitski
3940
*/
4041
public class SessionInformation implements Serializable {
4142

@@ -49,13 +50,17 @@ public class SessionInformation implements Serializable {
4950

5051
private boolean expired = false;
5152

52-
public SessionInformation(Object principal, String sessionId, Date lastRequest) {
53+
private final Date createdTime;
54+
55+
public SessionInformation(Object principal, String sessionId, Date lastRequest, Date createdTime) {
5356
Assert.notNull(principal, "Principal required");
5457
Assert.hasText(sessionId, "SessionId required");
5558
Assert.notNull(lastRequest, "LastRequest required");
59+
Assert.notNull(lastRequest, "CreatedTime required");
5660
this.principal = principal;
5761
this.sessionId = sessionId;
5862
this.lastRequest = lastRequest;
63+
this.createdTime = createdTime;
5964
}
6065

6166
public void expireNow() {
@@ -74,6 +79,10 @@ public String getSessionId() {
7479
return this.sessionId;
7580
}
7681

82+
public Date getCreatedTime() {
83+
return this.createdTime;
84+
}
85+
7786
public boolean isExpired() {
7887
return this.expired;
7988
}

core/src/main/java/org/springframework/security/core/session/SessionRegistryImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ public void registerNewSession(String sessionId, Object principal) {
133133
if (this.logger.isDebugEnabled()) {
134134
this.logger.debug(LogMessage.format("Registering session %s, for principal %s", sessionId, principal));
135135
}
136-
this.sessionIds.put(sessionId, new SessionInformation(principal, sessionId, new Date()));
136+
Date currentDate = new Date();
137+
this.sessionIds.put(sessionId, new SessionInformation(principal, sessionId, new Date(currentDate.getTime()),
138+
new Date(currentDate.getTime())));
137139
this.principals.compute(principal, (key, sessionsUsedByPrincipal) -> {
138140
if (sessionsUsedByPrincipal == null) {
139141
sessionsUsedByPrincipal = new CopyOnWriteArraySet<>();

core/src/test/java/org/springframework/security/core/session/SessionInformationTests.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* Tests {@link SessionInformation}.
2727
*
2828
* @author Ben Alex
29+
* @author Andrey Litvitski
2930
*/
3031
public class SessionInformationTests {
3132

@@ -34,10 +35,12 @@ public void testObject() throws Exception {
3435
Object principal = "Some principal object";
3536
String sessionId = "1234567890";
3637
Date currentDate = new Date();
37-
SessionInformation info = new SessionInformation(principal, sessionId, currentDate);
38+
SessionInformation info = new SessionInformation(principal, sessionId, new Date(currentDate.getTime()),
39+
new Date(currentDate.getTime()));
3840
assertThat(info.getPrincipal()).isEqualTo(principal);
3941
assertThat(info.getSessionId()).isEqualTo(sessionId);
4042
assertThat(info.getLastRequest()).isEqualTo(currentDate);
43+
assertThat(info.getCreatedTime()).isEqualTo(currentDate);
4144
Thread.sleep(10);
4245
info.refreshLastRequest();
4346
assertThat(info.getLastRequest().after(currentDate)).isTrue();

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/session/OidcSessionInformation.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ public class OidcSessionInformation extends SessionInformation {
4646
* @param user the OIDC Provider's session and end user
4747
*/
4848
public OidcSessionInformation(String sessionId, Map<String, String> authorities, OidcUser user) {
49-
super(user, sessionId, new Date());
49+
this(sessionId, authorities, user, new Date());
50+
}
51+
52+
private OidcSessionInformation(String sessionId, Map<String, String> authorities, OidcUser user, Date now) {
53+
super(user, sessionId, new Date(now.getTime()), new Date(now.getTime()));
5054
this.authorities = (authorities != null) ? new LinkedHashMap<>(authorities) : Collections.emptyMap();
5155
}
5256

web/src/test/java/org/springframework/security/web/authentication/session/ConcurrentSessionControlAuthenticationStrategyTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void setup() {
7070
this.request = new MockHttpServletRequest();
7171
this.response = new MockHttpServletResponse();
7272
this.sessionInformation = new SessionInformation(this.authentication.getPrincipal(), "unique",
73-
new Date(1374766134216L));
73+
new Date(1374766134216L), new Date());
7474
this.strategy = new ConcurrentSessionControlAuthenticationStrategy(this.sessionRegistry);
7575
}
7676

@@ -123,7 +123,7 @@ public void maxSessionsExpireExistingUser() {
123123
@Test
124124
public void maxSessionsExpireLeastRecentExistingUser() {
125125
SessionInformation moreRecentSessionInfo = new SessionInformation(this.authentication.getPrincipal(), "unique",
126-
new Date(1374766999999L));
126+
new Date(1374766999999L), new Date());
127127
given(this.sessionRegistry.getAllSessions(any(), anyBoolean()))
128128
.willReturn(Arrays.<SessionInformation>asList(moreRecentSessionInfo, this.sessionInformation));
129129
this.strategy.setMaximumSessions(2);
@@ -134,9 +134,9 @@ public void maxSessionsExpireLeastRecentExistingUser() {
134134
@Test
135135
public void onAuthenticationWhenMaxSessionsExceededByTwoThenTwoSessionsExpired() {
136136
SessionInformation oldestSessionInfo = new SessionInformation(this.authentication.getPrincipal(), "unique1",
137-
new Date(1374766134214L));
137+
new Date(1374766134214L), new Date());
138138
SessionInformation secondOldestSessionInfo = new SessionInformation(this.authentication.getPrincipal(),
139-
"unique2", new Date(1374766134215L));
139+
"unique2", new Date(1374766134215L), new Date());
140140
given(this.sessionRegistry.getAllSessions(any(), anyBoolean())).willReturn(
141141
Arrays.<SessionInformation>asList(oldestSessionInfo, secondOldestSessionInfo, this.sessionInformation));
142142
this.strategy.setMaximumSessions(2);
@@ -196,7 +196,7 @@ public void maxSessionsExpireExistingUserUsingSessionLimit() {
196196
@Test
197197
public void maxSessionsExpireLeastRecentExistingUserUsingSessionLimit() {
198198
SessionInformation moreRecentSessionInfo = new SessionInformation(this.authentication.getPrincipal(), "unique",
199-
new Date(1374766999999L));
199+
new Date(1374766999999L), new Date());
200200
given(this.sessionRegistry.getAllSessions(any(), anyBoolean()))
201201
.willReturn(Arrays.asList(moreRecentSessionInfo, this.sessionInformation));
202202
this.strategy.setMaximumSessions(SessionLimit.of(2));
@@ -207,9 +207,9 @@ public void maxSessionsExpireLeastRecentExistingUserUsingSessionLimit() {
207207
@Test
208208
public void onAuthenticationWhenMaxSessionsExceededByTwoThenTwoSessionsExpiredUsingSessionLimit() {
209209
SessionInformation oldestSessionInfo = new SessionInformation(this.authentication.getPrincipal(), "unique1",
210-
new Date(1374766134214L));
210+
new Date(1374766134214L), new Date());
211211
SessionInformation secondOldestSessionInfo = new SessionInformation(this.authentication.getPrincipal(),
212-
"unique2", new Date(1374766134215L));
212+
"unique2", new Date(1374766134215L), new Date());
213213
given(this.sessionRegistry.getAllSessions(any(), anyBoolean()))
214214
.willReturn(Arrays.asList(oldestSessionInfo, secondOldestSessionInfo, this.sessionInformation));
215215
this.strategy.setMaximumSessions(SessionLimit.of(2));

web/src/test/java/org/springframework/security/web/concurrent/ConcurrentSessionFilterTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ public void setLogoutHandlersWhenEmptyThenThrowsException() {
276276
private SessionRegistry mockSessionRegistry() {
277277
SessionRegistry registry = mock(SessionRegistry.class);
278278
SessionInformation information = new SessionInformation("user", "sessionId",
279-
new Date(System.currentTimeMillis() - 1000));
279+
new Date(System.currentTimeMillis() - 1000), new Date());
280280
information.expireNow();
281281
given(registry.getSessionInformation(anyString())).willReturn(information);
282282
return registry;

web/src/test/java/org/springframework/security/web/session/SessionInformationExpiredEventTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,22 @@ public void constructorWhenSessionInformationNullThenThrowsException() {
4343
@Test
4444
public void constructorWhenRequestNullThenThrowsException() {
4545
assertThatIllegalArgumentException().isThrownBy(() -> new SessionInformationExpiredEvent(
46-
new SessionInformation("fake", "sessionId", new Date()), null, new MockHttpServletResponse()));
46+
new SessionInformation("fake", "sessionId", new Date(), new Date()), null,
47+
new MockHttpServletResponse()));
4748
}
4849

4950
@Test
5051
public void constructorWhenResponseNullThenThrowsException() {
5152
assertThatIllegalArgumentException().isThrownBy(() -> new SessionInformationExpiredEvent(
52-
new SessionInformation("fake", "sessionId", new Date()), new MockHttpServletRequest(), null));
53+
new SessionInformation("fake", "sessionId", new Date(), new Date()), new MockHttpServletRequest(),
54+
null));
5355
}
5456

5557
@Test
5658
void constructorWhenFilterChainThenGetFilterChainReturnsNotNull() {
5759
MockFilterChain filterChain = new MockFilterChain();
5860
SessionInformationExpiredEvent event = new SessionInformationExpiredEvent(
59-
new SessionInformation("fake", "sessionId", new Date()), new MockHttpServletRequest(),
61+
new SessionInformation("fake", "sessionId", new Date(), new Date()), new MockHttpServletRequest(),
6062
new MockHttpServletResponse(), filterChain);
6163
assertThat(event.getFilterChain()).isSameAs(filterChain);
6264
}

0 commit comments

Comments
 (0)