2537-springsecurity系列--關於session的管理2-session緩存和共享


版本信息


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

踩得坑

  1. springboot 2.0以上的版本和 1.3版本的SpringSession在兼容上有些問題
  2. 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)

完整項目工程參考

https://github.com/starmoon1994/springsecurity-collection


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM