springboot+springsecurity+springsession实现session共享

作为一个稀有的Java妹子,所写的所有博客都只是当作自己的笔记,留下证据自己之前是有用心学习的~哈哈哈哈(如果有不对的地方,也请大家指出,不要悄悄咪咪的不告诉我)

一、前言

在工作中遇到多系统时,比如oa人事相关的是独立的系统,在其他系统登录后,在这个系统不应该再让用户重新登录,想实现一次登录,多系统session共享,有很多种实现方式,针对web业务可以使用springsession,如果是移动端业务可以使用jwt的token,今天主要记录spring session。

二、jar包准备

在此之前已经整合好springboot和spring security,且已经实现了spring security的登录功能,在这基础上实现session共享。

 <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>2.2.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
</dependency>

如果项目中有用到redis,引入过redis的包就不用重复引入redis的包

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

三、配置类

1、redis的配置类,如果项目有就不需要引入

@Configuration
@Slf4j
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * RedisTemplate配置
     *
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        //定义value的序列化方式
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

}

2、Springsession配置类

@Configuration
public class WebSessionConfiguration extends RedisHttpSessionConfiguration {

    public static String redisNamespace = "/supervision";
    @Value("${spring.session.redis.timeout:14400}")
    private int maxInactiveIntervalInSeconds;
    @Value("${spring.session.redis.flushMode:immediate}")
    private String flushMode;

    /**
     * 兼容1.X session的前缀,由于序列化问题,放弃兼容,改为其他方案、
     */
    static final String DEFAULT_SPRING_SESSION_REDIS_PREFIX = "spring:session:";

    @Bean
    public RedisIndexedSessionRepository sessionRepository() {
        RedisIndexedSessionRepository repository = super.sessionRepository();
        repository.setFlushMode(FlushMode.IMMEDIATE);
        repository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds);
        repository.setRedisKeyNamespace(DEFAULT_SPRING_SESSION_REDIS_PREFIX + redisNamespace);
        return repository;
    }

    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setUseBase64Encoding(false);
        return cookieSerializer;
    }
}

配置完成后,就可以直接使用,不需要再写其他代码了,在一个系统登录后,就可以直接访问另外一个系统,不需要再次登录。以下几点是我在使用过程中遇到的需要注意的点:
注意
1、springsecurity中继承User的类需要单独打成jar,在各个系统中引入,因为springsession在缓存session的时候,是以sessionId为key,value里存了class的全路径名,如果包名不一致的话会报类转换出错

java.lang.ClassCastException: com.nmpa.risk.entity.AuthUserDetail cannot be cast to com.security.demo.configuration.web.AuthUserDetail

2、跨域问题,sessionId的生成是在同一个域名下保证生成一个,如果两个系统的域名不一样,session是无法共享的,可以使用nginx进行转发解决。

四、源码解析

我是参考的另一篇文章的,主要就是使用了SessionRepositoryFilter过滤器,所有请求都经过这个过滤器,在这个过滤器中重写了getSession的方法,会去redis里取。原文链接:https://www.cnblogs.com/54chensongxia/p/12096493.html

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值