无法在 Hazelcast 中存储 spring 会话

Unable to store spring session in Hazelcast

我正在开发一个 spring 带有表单登录的启动应用程序。如果我的应用程序作为多个副本运行,我会遇到问题。

当我检查会话所在的位置时,我发现了 InMemoryWebSessionStore 服务。我明白了问题的根源。我确保我必须将会话存储在像 redis、hazelcast 这样的中心点。

我研究了如何做到这一点,我读到我应该使用 spring-session。

我遇到了以下错误:

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

首先我走的路对吗?谁有更好的解决方案?

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 {}

依赖关系:

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")

我走对了吗?你有更好的解决方案吗?

你知道我遇到的错误吗?

这是我用 Hazelcast 实现 Spring 会话所做的工作。

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());
  }
}

在我的 pom.xml 中,我有以下内容:

<dependency>
  <groupId>com.hazelcast</groupId>
  <artifactId>hazelcast</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-hazelcast</artifactId>
</dependency>

我没有设置 spring.session.store 类型。您可以根据需要定制配置(添加 kubernetes 支持,将其用作分布式查询缓存等)。