Implementing Shared Session in Spring Boot with Shiro and Redis Using CrazyCake Plugin
This tutorial demonstrates how to enable shared HTTP sessions across multiple Spring Boot instances by integrating Apache Shiro with Redis via the CrazyCake plugin, configuring Maven dependencies, Redis and Shiro settings, building service and controller layers, and deploying the applications behind an Nginx load balancer for seamless session persistence.
This article explains how to extend a single‑node Spring Boot + Shiro project to support shared sessions across multiple instances using Redis as the session store.
Instead of writing a custom RedisManager or SessionDAO , the author leverages the open‑source crazycake plugin, which provides ready‑made Redis integration for Shiro.
pom.xml dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.1.0</version>
</dependency>Redis configuration (redis.properties)
shiro.redis.host=localhost:6379
shiro.redis.timeout=1800000RedisConfig.java
@Configuration
@PropertySource("classpath:conf/redis.properties")
public class RedisConfig {
@Value("${shiro.redis.host}")
private String host;
@Value("${shiro.redis.timeout}")
private int timeout;
// getters and setters omitted for brevity
}ShiroConfig.java wires the Redis manager, session DAO, cookie, and session manager, then builds the DefaultWebSecurityManager and ShiroFilterFactoryBean with URL filter chains.
@Bean
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost(redisConfig().getHost());
redisManager.setTimeout(redisConfig().getTimeout());
return redisManager;
}
@Bean
public RedisSessionDAO sessionDAO() {
RedisSessionDAO dao = new RedisSessionDAO();
dao.setRedisManager(redisManager());
dao.setSessionIdGenerator(sessionIdGenerator());
return dao;
}
@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager manager = new DefaultWebSessionManager();
manager.setGlobalSessionTimeout(redisConfig().getTimeout());
manager.setSessionIdCookie(cookie());
manager.setSessionDAO(sessionDAO());
return manager;
}The service layer stores user objects in Redis using RedisTemplate<String, User> , and the controller provides REST endpoints for login, registration, and a protected home page.
To run the demo in a clustered environment, two JARs are built (ports 8081 and 8082) and an Nginx upstream is configured to balance traffic:
upstream myapp {
server 127.0.0.1:8081 weight=1;
server 127.0.0.1:8082 weight=1;
}
server {
listen 80;
server_name myapp;
location / {
proxy_pass http://myapp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}After starting both Spring Boot instances and Nginx, users can register on one node, log in, and then refresh the other node without re‑authenticating, demonstrating successful session sharing.
The complete source code is available on GitHub: https://github.com/Mysakura/boot-shiro-session .
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.