I wrote a little spring security demo some time ago and I used redis for storing user sessions. I've been trying to upgrade it to Spring Boot 3 and Spring Security 6 but after raising project versions as follows:
Java: 11 -> 17
Spring Boot: 2.7.5 -> 3.0.4
I can no longer autowire org.springframework.session.FindByIndexNameSessionRepository
This is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>spring-security-jpa-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-security-jpa-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>17</source>
<target>17</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.3.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is my redis config in application.properties:
...
spring.session.store-type=redis
spring.session.redis.namespace=spring-security-jpa-demo
spring.data.redis.host=localhost
spring.data.redis.password=redis
spring.data.redis.port=6379
...
And I have redis and redis commander services in docker compose:
version: '3.7'
volumes:
spring-security-jpa-demo-redis-data:
name: spring-security-jpa-demo-redis-data
driver: local
networks:
spring-security-jpa-demo:
name: spring-security-jpa-demo
driver: bridge
services:
redis:
image: redis:5-alpine
volumes:
- spring-security-jpa-demo-redis-data:/data
command: redis-server --requirepass redis
networks:
- spring-security-jpa-demo
restart: always
ports:
- "6379:6379"
redis-commander:
image: rediscommander/redis-commander:latest
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: redis
networks:
- spring-security-jpa-demo
ports:
- "8081:8081"
depends_on:
- redis
...
And this is how I was using the FindByIndexNameSessionRepository:
package com.example.springsecurityjpademo.session;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class RedisSessionHandler {
private final FindByIndexNameSessionRepository<? extends Session> sessionRepository;
public void removeAllUserSessions(String principalName) {
log.debug("Removing all sessions for user: {}", principalName);
sessionRepository.findByPrincipalName(principalName)
.forEach((id, session) -> sessionRepository.deleteById(session.getId()));
}
public void removeUserSession(String principalName, String sessionId) {
var sessionOptional = sessionRepository.findByPrincipalName(principalName)
.values().stream().filter(session -> sessionId.equals(session.getId())).findFirst();
sessionOptional.ifPresent(session -> sessionRepository.deleteById(session.getId()));
}
}
Since the version upgrades the application fails to start with this error:
Description:
Parameter 0 of constructor in com.example.springsecurityjpademo.session.RedisSessionHandler required a bean of type 'org.springframework.session.FindByIndexNameSessionRepository' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.session.FindByIndexNameSessionRepository' in your configuration.
I've tried removing the store-type property from application.properties and using the @EnableRedisHttpSession but with no success. Should this bean be manually configured now or am I just missing something in my configuration?
Note that I am not running the app in a docker container, I am trying to run it locally first so that's why spring.data.redis.host is set to localhost.
Thanks in advance!
I had the same issue but I solved it.
You use @EnableRedisIndexedHttpSession
instead of @EnableRedisHttpSession
.
Please see following GitHub issue.
https://github.com/spring-projects/spring-session/issues/2235#issuecomment-1434657799