T. Ç
T. Ç

Reputation: 145

Unable to store spring session in Hazelcast

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

Answers (1)

Lee Greiner
Lee Greiner

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

Related Questions