关于spring session redis共享session的跨子域的处理

安装完redis, spring端只要下面这两个bean配置上就可以用了

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version= "1.0"  encoding= "UTF-8" ?>
<beans xmlns= "http://www.springframework.org/schema/beans"
     xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context= "http://www.springframework.org/schema/context"
     xmlns:p= "http://www.springframework.org/schema/p"
     xsi:schemaLocation="http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
         http: //www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean  class = "org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />
 
<bean id= "jedisConnectionFactory"  class = "org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
     <property name= "port"  value= "${redis_port}"  />
     <property name= "hostName"  value= "${redis_url}"  />
</bean>

 

官方示例都是零配置的写法,画风变的太大以至于在AbstractHttpSessionApplicationInitializer这里浪费了 很久。其实用上面这种方式,是完全不需要再写AbstractHttpSessionApplicationInitializer的,他们干的是一件 事。

关于子域的坑

发现spring session在获取sessionid时,在CookieHttpSessionStrategy中并没有做跨子域的处理...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private  Cookie createSessionCookie(HttpServletRequest request,
            Map<String, String> sessionIds) {
        Cookie sessionCookie =  new  Cookie(cookieName, "" );
        if (isServlet3Plus) {
            sessionCookie.setHttpOnly( true );
        }
        sessionCookie.setSecure(request.isSecure());
        sessionCookie.setPath(cookiePath(request));
        // TODO set domain?
        ...
 
    private  static  String cookiePath(HttpServletRequest request) {
        return  request.getContextPath() +  "/" ;
    }

 

其实这里只要把cookiePath的返回值设置为统一的根路径就能让session id从根域获取了,这样同根下的所有web应用就可以轻松实现单点登录共享session了。既然找到了问题,解决就容易多了,下面列几种解决方案:

  1. 改spring session源码,并重新打包
  2. 代码复用CookieHttpSessionStrategy,改cookiePath,并在spring注入时指定自己写的这份Strategy

搭建spring session源码的开发环境太麻烦了,我用的方案2

1
2
3
private  static  String cookiePath(HttpServletRequest request) {
     return  "/" ;
}

 并在spring redis中加入如下配置

1
2
3
4
5
6
7
8
<bean id= "redisRepository"  class = "org.springframework.session.data.redis.RedisOperationsSessionRepository" >
         <constructor-arg ref= "jedisConnectionFactory"  />
</bean>
<bean id= "cookieHttpSessionStrategy"  class = "reyo.sdk.utils.spring.CookieHttpSessionStrategy" />
<bean  class = "org.springframework.session.web.http.SessionRepositoryFilter" >
     <constructor-arg ref= "redisRepository"  />
     <property name= "httpSessionStrategy"  ref= "cookieHttpSessionStrategy" />
</bean>

 搞定(spring 4.3.0不支持)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值