版本信息
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>1.5.14.RELEASE</version>
<!--實際里面spring-security-web的版本是4.2.7-->
</dependency>
需求
1.服務器重啟后,用戶不需要重新登錄,進行session緩存
2.用戶登錄后,半小時內無操作,則將其session置為無效
3.多台服務器部署成應用集群,進行session共享
4.想自定義前端cookie的名稱,不用用自定義的JSESSION名稱
處理需求
需求1
SpringSession和SpringSecurity可自動配合,SpringSecurity會向SpringSession獲取session信息和授權信息,並進行緩存,
在應用重啟后,SpringSecurity獲取到的是Redis中緩存的session信息,即可完成重啟后不重復登錄
需求2
配置server.session.timeout參數,單位是秒,最小值是一分鍾即60秒,假設server.session.timeout=60,用戶在登錄后,會在redis存一條session信息
如果60秒內沒有任何操作,該條session將失效。如果用戶一直有操作和請求,SpringSession會刷新有效期,每次請求后都將重新計算60秒。
需求3
應用在配置時,公用一台Redis服務器即可,所有應用的SpringSecurity都會通過SpringSession來存取session,而SpringSession都指向同一台Redis服務器,即可達到session共享的效果
需求4
自定義一個CookieHttpSessionStrategy即可
@Bean
public CookieHttpSessionStrategy cookieHttpSessionStrategy() {
CookieHttpSessionStrategy strategy = new CookieHttpSessionStrategy();
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setCookieName("gs");
cookieSerializer.setCookiePath("/");
cookieSerializer.setCookieMaxAge(60 * 60 * 24 * 30);
strategy.setCookieSerializer(cookieSerializer);
return strategy;
}
使用spring-session組件來管理web應用的session
依賴文件
springboot的版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
redis依賴和springsession的依賴
<!--redis依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<!--spring2.0以后默認的客戶端是lettuce 需要手動指定成redis-->
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--redis依賴-->
<!--springsession的依賴-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<!--springsession的依賴-->
配置application.properties的配置文件
# spring session采用的數據源類型
spring.session.store-type=redis
#配置session在redis里的命名空間
#spring.session.redis.namespace=security_session
#配置session的保存觸發方式
#spring.session.redis.flush-mode=on_save
# 應用的session過期時間
server.session.timeout=1800
redis配置參數
#The Redis settings
# Redis數據庫索引(默認為0)
spring.redis.database=9
# Redis服務器地址
spring.redis.host=localhost
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認為空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連接池中的最大空閑連接
spring.redis.pool.max-idle=8
# 連接池中的最小空閑連接
spring.redis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=0
Redis初始化類
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableAutoConfiguration
public class RedisConfig {
private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Bean
@ConfigurationProperties(prefix = "spring.redis")
public JedisPoolConfig getRedisConfig() {
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
@Bean
@ConfigurationProperties(prefix = "spring.redis")
public JedisConnectionFactory getConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
JedisPoolConfig config = getRedisConfig();
factory.setPoolConfig(config);
logger.info("JedisConnectionFactory bean init success.");
return factory;
}
@Bean
public RedisTemplate<?, ?> getRedisTemplate() {
RedisTemplate<?, ?> template = new StringRedisTemplate(getConnectionFactory());
return template;
}
}
踩得坑
- springboot 2.0以上的版本和 1.3版本的SpringSession在兼容上有些問題
- 1.3版本的SpringSession可正常使用Redis進行session緩存,1.3版本的SpringSession在使用MongoDB時,會出現數據格式不兼容(存進去的數據和取出的數據不同,導致報錯)
參考和官方文檔:
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/java-security.html
官方文檔 使用spring-session來給sec提供session緩存支持
https://docs.spring.io/spring-session-data-mongodb/docs/2.0.2.RELEASE/reference/htmlsingle/boot-mongo.html
Spring Session - Mongo Repositories
https://docs.spring.io/spring-session-data-mongodb/docs/2.0.2.RELEASE/reference/htmlsingle/
使用mongodb管理session的文檔
https://docs.spring.io/spring-session/docs/1.3.3.RELEASE/reference/html5/
spring-session1.3.3的文檔 里面詳細說明和demo(1.3.3操作redis的客戶端換成了 Lettuce)