Reputation: 145
I'm developing a spring boot application with form login. I have a problem if my application works as more than one replica.
When I check where session is located, I found InMemoryWebSessionStore service. And I understood the source of the problem. I made sure that I had to store the session in a central point like redis, hazelcast.
I researched how to do this, and I read that I should use spring-session.
I faced following error:
Caused by: org.springframework.boot.autoconfigure.session.SessionRepositoryUnavailableException: No session repository could be auto-configured, check your configuration (session store type is 'hazelcast')
application.yml:
spring:
session:
store-type: hazelcast
First of all am I on the right way? Anyone have a better solution?
SecurityConfig.kt
@EnableWebFluxSecurity
class SecurityConfig {
@Bean
fun adminWebFilterChain(
http: ServerHttpSecurity,
userService: UserService,
passwordEncoder: PasswordEncoder
): SecurityWebFilterChain {
val userDetailsService = CustomUserDetailsService(userService, passwordEncoder)
val manager = CustomUserAuthenticationManager(userDetailsService)
manager.setPasswordEncoder(passwordEncoder)
return http
.csrf().disable()
.authenticationManager(manager)
.authorizeExchange()
.pathMatchers("/login", "/logout").permitAll()
.anyExchange().authenticated()
.and().formLogin()
.and().logout()
.and().build()
}
@Bean
fun passwordEncoder(): PasswordEncoder {
return BCryptPasswordEncoder()
}
}
HazelcastHttpSessionConfig.kt
@Configuration
@EnableHazelcastHttpSession
class HazelcastHttpSessionConfig {}
Dependencies:
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("io.micrometer:micrometer-registry-prometheus")
implementation("org.springframework.session:spring-session-core")
implementation("org.springframework.session:spring-session-hazelcast")
Am I on the right way? Do you have a better solution?
And do you have any idea about an error that I faced?
Upvotes: 0
Views: 2019
Reputation: 1082
Here is what I have done to implement Spring Session with Hazelcast.
HazelcastConfig.java
@Configuration
@EnableHazelcastHttpSession(maxInactiveIntervalInSeconds = 3600)
public class HazelcastConfig {
@Bean
public Config hazelCastConfig() {
final Config config = new Config().setInstanceName("hazelcast-instance");
config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME)
.addMapAttributeConfig(springSessionAttributeConfig()).addMapIndexConfig(
new MapIndexConfig(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
return config;
}
private MapAttributeConfig springSessionAttributeConfig() {
return new MapAttributeConfig()
.setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
.setExtractor(PrincipalNameExtractor.class.getName());
}
}
In my pom.xml I have the following:
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-hazelcast</artifactId>
</dependency>
I don't set the spring.session.store-type. You can tailor the configuration to your needs (adding kubernetes support, using it as a distributed query cache, etc).
Upvotes: 1