zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    flush table with read lock的轻量级解决方案
    Linux进程关系(转载)
    常用的linux系统监控命令
    MySQL 5.7 InnoDB缓冲池NUMA功能支持——但是别高兴的太早
    网站收集ing....
    【转】程序设计语言中的 一等公民,二等公民,三等公民
    sbt修改为阿里云镜像
    java 中的原始类型与原始封装类型
    【转】MySql中row_number()、rank()、dense_rank() 的区别
    WPS_word使用
  • 原文地址:https://www.cnblogs.com/starmoon1994/p/9362327.html
Copyright © 2011-2022 走看看