Introduce SessionIdGenerationStrategy
Closes gh-11
This commit is contained in:
committed by
Marcus Hert Da Coregio
parent
2e1275333a
commit
d547b33962
@@ -62,6 +62,8 @@ import org.springframework.session.MapSession;
|
||||
import org.springframework.session.PrincipalNameIndexResolver;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionIdGenerationStrategy;
|
||||
import org.springframework.session.UuidSessionIdGenerationStrategy;
|
||||
import org.springframework.transaction.support.TransactionOperations;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -252,6 +254,8 @@ public class JdbcIndexedSessionRepository implements
|
||||
|
||||
private ThreadPoolTaskScheduler taskScheduler;
|
||||
|
||||
private SessionIdGenerationStrategy sessionIdGenerationStrategy = UuidSessionIdGenerationStrategy.getInstance();
|
||||
|
||||
/**
|
||||
* Create a new {@link JdbcIndexedSessionRepository} instance which uses the provided
|
||||
* {@link JdbcOperations} and {@link TransactionOperations} to manage sessions.
|
||||
@@ -461,7 +465,7 @@ public class JdbcIndexedSessionRepository implements
|
||||
|
||||
@Override
|
||||
public JdbcSession createSession() {
|
||||
MapSession delegate = new MapSession();
|
||||
MapSession delegate = new MapSession(this.sessionIdGenerationStrategy);
|
||||
delegate.setMaxInactiveInterval(this.defaultMaxInactiveInterval);
|
||||
JdbcSession session = new JdbcSession(delegate, UUID.randomUUID().toString(), true);
|
||||
session.flushIfRequired();
|
||||
@@ -686,6 +690,16 @@ public class JdbcIndexedSessionRepository implements
|
||||
TypeDescriptor.valueOf(Object.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link SessionIdGenerationStrategy} to use to generate session ids.
|
||||
* @param sessionIdGenerationStrategy the {@link SessionIdGenerationStrategy} to use
|
||||
* @since 3.2
|
||||
*/
|
||||
public void setSessionIdGenerationStrategy(SessionIdGenerationStrategy sessionIdGenerationStrategy) {
|
||||
Assert.notNull(sessionIdGenerationStrategy, "sessionIdGenerationStrategy cannot be null");
|
||||
this.sessionIdGenerationStrategy = sessionIdGenerationStrategy;
|
||||
}
|
||||
|
||||
private enum DeltaValue {
|
||||
|
||||
ADDED, UPDATED, REMOVED
|
||||
@@ -721,7 +735,7 @@ public class JdbcIndexedSessionRepository implements
|
||||
*/
|
||||
final class JdbcSession implements Session {
|
||||
|
||||
private final Session delegate;
|
||||
private final MapSession delegate;
|
||||
|
||||
private final String primaryKey;
|
||||
|
||||
@@ -773,7 +787,9 @@ public class JdbcIndexedSessionRepository implements
|
||||
@Override
|
||||
public String changeSessionId() {
|
||||
this.changed = true;
|
||||
return this.delegate.changeSessionId();
|
||||
String newSessionId = JdbcIndexedSessionRepository.this.sessionIdGenerationStrategy.generate();
|
||||
this.delegate.setId(newSessionId);
|
||||
return newSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -50,6 +50,8 @@ import org.springframework.session.IndexResolver;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionIdGenerationStrategy;
|
||||
import org.springframework.session.UuidSessionIdGenerationStrategy;
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
|
||||
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
|
||||
@@ -109,6 +111,8 @@ public class JdbcHttpSessionConfiguration implements BeanClassLoaderAware, Embed
|
||||
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
private SessionIdGenerationStrategy sessionIdGenerationStrategy = UuidSessionIdGenerationStrategy.getInstance();
|
||||
|
||||
@Bean
|
||||
public JdbcIndexedSessionRepository sessionRepository() {
|
||||
JdbcTemplate jdbcTemplate = createJdbcTemplate(this.dataSource);
|
||||
@@ -144,6 +148,7 @@ public class JdbcHttpSessionConfiguration implements BeanClassLoaderAware, Embed
|
||||
else {
|
||||
sessionRepository.setConversionService(createConversionServiceWithBeanClassLoader(this.classLoader));
|
||||
}
|
||||
sessionRepository.setSessionIdGenerationStrategy(this.sessionIdGenerationStrategy);
|
||||
this.sessionRepositoryCustomizers
|
||||
.forEach((sessionRepositoryCustomizer) -> sessionRepositoryCustomizer.customize(sessionRepository));
|
||||
return sessionRepository;
|
||||
@@ -235,6 +240,11 @@ public class JdbcHttpSessionConfiguration implements BeanClassLoaderAware, Embed
|
||||
this.sessionRepositoryCustomizers = sessionRepositoryCustomizers.orderedStream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setSessionIdGenerationStrategy(SessionIdGenerationStrategy sessionIdGenerationStrategy) {
|
||||
this.sessionIdGenerationStrategy = sessionIdGenerationStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2014-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.jdbc;
|
||||
|
||||
import org.springframework.session.SessionIdGenerationStrategy;
|
||||
|
||||
public class FixedSessionIdGenerationStrategy implements SessionIdGenerationStrategy {
|
||||
|
||||
private final String id;
|
||||
|
||||
public FixedSessionIdGenerationStrategy(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -263,6 +263,12 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
assertThat(this.repository).extracting("taskScheduler").isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void setSessionIdGenerationStrategyWhenNullThenException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setSessionIdGenerationStrategy(null))
|
||||
.withMessage("sessionIdGenerationStrategy cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createSessionDefaultMaxInactiveInterval() {
|
||||
JdbcSession session = this.repository.createSession();
|
||||
@@ -769,4 +775,32 @@ class JdbcIndexedSessionRepositoryTests {
|
||||
verify(lobCreator, atLeastOnce()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createSessionWhenSessionIdGenerationStrategyThenUses() {
|
||||
this.repository.setSessionIdGenerationStrategy(() -> "test");
|
||||
JdbcSession session = this.repository.createSession();
|
||||
assertThat(session.getId()).isEqualTo("test");
|
||||
assertThat(session.changeSessionId()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setSessionIdGenerationStrategyWhenNullThenThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.repository.setSessionIdGenerationStrategy(null))
|
||||
.withMessage("sessionIdGenerationStrategy cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByIdWhenChangeSessionIdThenUsesSessionIdGenerationStrategy() {
|
||||
this.repository.setSessionIdGenerationStrategy(() -> "test");
|
||||
Session saved = this.repository.new JdbcSession(new MapSession(), "primaryKey", false);
|
||||
saved.setAttribute("savedName", "savedValue");
|
||||
given(this.jdbcOperations.query(isA(String.class), isA(PreparedStatementSetter.class),
|
||||
isA(ResultSetExtractor.class))).willReturn(Collections.singletonList(saved));
|
||||
|
||||
JdbcSession session = this.repository.findById(saved.getId());
|
||||
|
||||
assertThat(session.getId()).isEqualTo(saved.getId());
|
||||
assertThat(session.changeSessionId()).isEqualTo("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,10 @@ import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.IndexResolver;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionIdGenerationStrategy;
|
||||
import org.springframework.session.UuidSessionIdGenerationStrategy;
|
||||
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||
import org.springframework.session.jdbc.FixedSessionIdGenerationStrategy;
|
||||
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
|
||||
import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
@@ -318,11 +321,40 @@ class JdbcHttpSessionConfigurationTests {
|
||||
assertThat(sessionRepository).extracting("defaultMaxInactiveInterval").isEqualTo(Duration.ZERO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sessionIdGenerationStrategyWhenCustomBeanThenUses() {
|
||||
registerAndRefresh(DataSourceConfiguration.class, CustomSessionIdGenerationStrategyConfiguration.class);
|
||||
JdbcIndexedSessionRepository sessionRepository = this.context.getBean(JdbcIndexedSessionRepository.class);
|
||||
SessionIdGenerationStrategy sessionIdGenerationStrategy = (SessionIdGenerationStrategy) ReflectionTestUtils
|
||||
.getField(sessionRepository, "sessionIdGenerationStrategy");
|
||||
assertThat(sessionIdGenerationStrategy).isInstanceOf(FixedSessionIdGenerationStrategy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sessionIdGenerationStrategyWhenNoBeanThenDefault() {
|
||||
registerAndRefresh(DataSourceConfiguration.class, DefaultConfiguration.class);
|
||||
JdbcIndexedSessionRepository sessionRepository = this.context.getBean(JdbcIndexedSessionRepository.class);
|
||||
SessionIdGenerationStrategy sessionIdGenerationStrategy = (SessionIdGenerationStrategy) ReflectionTestUtils
|
||||
.getField(sessionRepository, "sessionIdGenerationStrategy");
|
||||
assertThat(sessionIdGenerationStrategy).isInstanceOf(UuidSessionIdGenerationStrategy.class);
|
||||
}
|
||||
|
||||
private void registerAndRefresh(Class<?>... annotatedClasses) {
|
||||
this.context.register(annotatedClasses);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableJdbcHttpSession
|
||||
static class CustomSessionIdGenerationStrategyConfiguration {
|
||||
|
||||
@Bean
|
||||
SessionIdGenerationStrategy sessionIdGenerationStrategy() {
|
||||
return new FixedSessionIdGenerationStrategy("my-id");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableJdbcHttpSession
|
||||
static class NoDataSourceConfiguration {
|
||||
|
||||
Reference in New Issue
Block a user