Skip to content

Commit eb9f62a

Browse files
committed
Update principal index on session ID change
Closes gh-1791
1 parent 418cb60 commit eb9f62a

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryITests.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2020 the original author or authors.
2+
* Copyright 2014-2021 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.
@@ -473,6 +473,60 @@ void findByChangedSecurityPrincipalNameReload() {
473473
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
474474
}
475475

476+
@Test // gh-1791
477+
void changeSessionIdWhenSessionExpiresThenRemovesAllPrincipalIndexIds() {
478+
RedisSession toSave = this.repository.createSession();
479+
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
480+
481+
this.repository.save(toSave);
482+
String usernameSessionKey = "RedisIndexedSessionRepositoryITests:index:" + INDEX_NAME + ":" + getSecurityName();
483+
484+
RedisSession findById = this.repository.findById(toSave.getId());
485+
String originalFindById = findById.getId();
486+
487+
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).contains(originalFindById);
488+
489+
String changeSessionId = findById.changeSessionId();
490+
findById.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
491+
492+
this.repository.save(findById);
493+
494+
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).contains(changeSessionId);
495+
496+
String body = "RedisIndexedSessionRepositoryITests:sessions:expires:" + changeSessionId;
497+
String channel = "__keyevent@0__:expired";
498+
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
499+
body.getBytes(StandardCharsets.UTF_8));
500+
byte[] pattern = new byte[] {};
501+
this.repository.onMessage(message, pattern);
502+
503+
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).isEmpty();
504+
}
505+
506+
@Test
507+
void changeSessionIdWhenPrincipalNameChangesThenNewPrincipalMapsToNewSessionId() {
508+
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
509+
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
510+
RedisSession toSave = this.repository.createSession();
511+
toSave.setAttribute(INDEX_NAME, principalName);
512+
513+
this.repository.save(toSave);
514+
515+
RedisSession findById = this.repository.findById(toSave.getId());
516+
String changeSessionId = findById.changeSessionId();
517+
findById.setAttribute(INDEX_NAME, principalNameChanged);
518+
this.repository.save(findById);
519+
520+
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
521+
principalName);
522+
assertThat(findByPrincipalName).isEmpty();
523+
524+
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
525+
526+
assertThat(findByPrincipalName).hasSize(1);
527+
assertThat(findByPrincipalName.keySet()).containsOnly(changeSessionId);
528+
}
529+
476530
@Test
477531
void changeSessionIdWhenOnlyChangeId() {
478532
String attrName = "changeSessionId";

spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisIndexedSessionRepository.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2020 the original author or authors.
2+
* Copyright 2014-2021 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.
@@ -858,6 +858,11 @@ private void saveChangeSessionId() {
858858
catch (NonTransientDataAccessException ex) {
859859
handleErrNoSuchKeyError(ex);
860860
}
861+
String originalPrincipalRedisKey = getPrincipalKey(this.originalPrincipalName);
862+
RedisIndexedSessionRepository.this.sessionRedisOperations.boundSetOps(originalPrincipalRedisKey)
863+
.remove(this.originalSessionId);
864+
RedisIndexedSessionRepository.this.sessionRedisOperations.boundSetOps(originalPrincipalRedisKey)
865+
.add(sessionId);
861866
}
862867
this.originalSessionId = sessionId;
863868
}

0 commit comments

Comments
 (0)