论坛首页 Java企业应用论坛

weblogic之同域下session冲突解决

浏览 6350 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-05-29  

这两天在搭一个环境,要求把金税三期的三个子系统(系统A、系统B、系统C)合并成一个部署,由于3个子系统相互之间有些配置文件冲突无法放在一个应用下部署,只好随找了2台机器,建了3个domain来部署。也许有人问,在1个domain下部署3个应用也可以吧,事实我也想这么部署,但由于公司框架要求上下文根必须为/,那这种方式部署就不行了。


3个系统部署在3个domain下,且使用了不同的ip和端口,如何才能让用户看起来是在一起呢?相信大家也有了答案,使用apache http server或nginx等之类的web服务器做代理实现。遂使用nginx搭建环境,搞定之。代理主要的配置如下:

#转发系统B管理

location ~ /jxgl/ {

proxy_pass http://192.168.40.134:8001;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header  X-Real-IP  $remote_addr;

proxy_set_header Host $host;

}


#转发系统C

location ~ /zcpg/ {

proxy_pass http://192.168.40.134:8002;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header  X-Real-IP  $remote_addr;

proxy_set_header Host $host;

}


#转发系统A管理

location ~ /fxgl/ {

proxy_pass http://192.168.110.121:7001;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header  X-Real-IP  $remote_addr;

proxy_set_header Host $host;

}


#转发其他所有

location ~ /.* {

proxy_pass http://192.168.110.121:7001;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header  X-Real-IP  $remote_addr;

proxy_set_header Host $host;

}

 

由配置可以看出,以/zcpg开头的应用,转发到http://192.168.40.134:8002,以/jxgl开头的应用,转发到http://192.168.110.121:7001,以 /fxgl开头的应用,转发到http://192.168.110.121:7001,其他的都转发到http://192.168.110.121:7001


单点登录问题随之而来,由于部门暂无单点登录产品,且目前无时间临时加上单点登录,只好让三个系统各自登录各自的系统。由于三个系统的登录地址完全一样,故做了一点配置上的改动,把系统B和系统C的登录和提交界面的url添加上了后缀。这样3个系统可以访问自己的登录url单独登录。改动后ngix增加代理的配置

#转发系统C__登录

location ~ .*_zcpg\.(webfaster|html|htm){

proxy_pass http://192.168.40.134:8002;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header  X-Real-IP  $remote_addr;

proxy_set_header Host $host;

}

#转发系统B管理__登录

location ~ .*_jxgl\.(webfaster|html|htm){

proxy_pass http://192.168.40.134:8001;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header  X-Real-IP  $remote_addr;

proxy_set_header Host $host;

}

 


至此,本以为万事大吉,结果登录过程中还是遇到了麻烦。先登录系统A,然后再登录系统B,结果系统B登录成功后,系统A却意外的退出了。仔细翻查了代码和配置,3个系统的登录过程完全是隔离开的,系统B的会话不会影响系统A的会话。


经过httpwatch跟踪登录过程,意外发现在系统B登录过程中,cookie中的jsessionid值被修改了。登录系统A成功后,再登录系统B,这是jsessionid被系统B的应用改了其他值,导致了系统A登录信息的丢失,以致被系统任务登录失效了。


众所周知,服务器端session是以jsessionid来识别是不是同一个会话,当客户端开启cookie时,会在cookie中设置jsessionid。客户端未开启时,会以url的方式传递jsessionid。问题的原因显然是weblogic初始化session时,如果session还未初始化,没有使用客户端传递的jsessionid来初始化(据说tomcat会使用客户端传递的jsessionid)。


问题找到了,解决办法就有2种方法。1是让weblogic使用客户端的jsessionid来初始化session 2是让每个应用使用不同的key来存储jsessionid的值。即系统A使用jsessionid,系统B使用jsessionidjxgl,系统C使用jsessionidzcpg。

第1种方法不知道怎么配置,第2中方法比较简单,直接配置WEB-INF\weblogic.xml即可。weblogic.xml增加如下配置:

<session-descriptor>
    <cookie-name>jsessionidjxgl</cookie-name>
</session-descriptor>

 
至此,问题解决。

 

   发表时间:2013-06-01  
看了你的文章,对文章中后半段cookie和session的问题比较感兴趣,而且我以前也遇到过类似的问题,虽然对你们的环境不是很了解,但是我觉得虽然你采用了把每个应用的sessionid在cookie中的名字改变并解决了问题,但是其中对具体原因的分析有些偏差。

造成你这种情况的根本原因并不是什么session初始化的问题,浏览器发送什么cookie会根据三个因素确定:
domain
path
security(如http或https)

1.你在nginx背后虽然有三个domain,但是我记得如果不显示指定session的domain的话,服务器是不会发送domain信息,那么浏览器会根据你当前的ip地址来确定这个cookie的domain,所以你这三个应用的domain是一样的。
2.security肯定是一样的,http.
3.应用的context是/,那么默认的path就是context,也就是说这三个应用的cookie的path也是一样的。

因此如果都是同样使用jsessionid作为session的cookie的名字的话,这三个应用的cookie是会被相互覆盖的,也就出现你在文中提到的cookie的jessionid的值被修改的问题。因此通过修改session的cookie名字是可以解决这个问题。但是其他的同名cookie也会被相互修改,不能从根本上解决问题。你可以测试以下。


另外,cookie禁用通过url重写的方式加入sessionid的机制不是浏览器来确定和发起的,而是server来识别和主动将地址重写的,HttpServletResponse中有一个方法可以帮你做这个事情,<c:url>也可以。
0 请登录后投票
   发表时间:2013-06-05  
楼主的解决方式很棒!

1楼的分析也很棒!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics