文档章节

关于Websphere 会话管理若干奇葩问题

stamen
 stamen
发布于 2015/12/09 20:28
字数 1463
阅读 1418
收藏 4

引言

      由于最近在做应用集成平台,即实现独立部署的WAR包可以在同一个集成平台中访问。被集成的业务组件为什么可以在集成平台实现页面集成,主要通过以下几个步骤实现:

  ①用户登录集成平台系统;
  ②集成平台加载业务组件菜单,业务组件菜单的URL自动添加一个会话凭据,即会话token。这样点击这个组件菜单,将向独立部署的业务组件服务发送页面请求;
  ③这个页面请求被安装在业务组件中的集成插件(其实是一个HttpFilter)截获,并执行以下操作:
     1)集成插件通过向集成平台发送REST请求验证token的合法性,如果不合法将请求重定向
      到集成平台的登录页面,否则执行下一步操作;
     2)根据token再次发送REST请求,获取对应的会话用户信息(如用户名,所有单位等)。
  ④根据远程获取的用户会话信息产生业务组件本地的会话(即本地的HttpSession),创建本地会话后,即可正常打开被集成到集成平台的业务组件菜单页面了。

     图1 平台集成结构图

    由于集成平台提供的验证token合法性、根据token获取会话用户信息等Rest服务都是工作于会话环境下,因此我的设计是token即取自会话的ID(即HttpSession.getId()),换句话说,token即是会话的ID。在集成插件中,通过发送如下的Rest请求调用集成平台的Web Service:

   http://<集成平台url>;jsessionid=<token>?xxx=yyy...

    以下是通过URL传递会话的标准写法,在Jetty,Tomcat等应用服务器下,集成平台都可为请求正确绑定HttpSession,但是在WebSphere下却不行,为了解决该问题花了我两天多时间,下面就回顾一下解决这个问题的整体过程。

Websphere默认未开启URL会话重写

    我们都知道维护客户端和服务端会话有两种实现方式,其一是通过URL会话重写,即上面所列的URL后加“;jsessionid=xxx”的方式,另一种是通过Cookie,在产生会话时,应用服务器向客户端Cookie中写一个名为JSESSIONID的会话ID,客户端每次请求时都将Cookie带上来,以下是一个会话Cookie的报文:

图 2 Cookie会话ID

     Jetty,Tomcat等应用服务器默认两种方式都支持,但是WebSphere默认只支持Cookie维护会话的方式,如果需要支持URL会话重写的方式,需要手工启用这个功能并重启应用服务器:


图 3 WebSphere启用URL重写

    由于我的集成插件默认是以添加";jsessionid=xxx"来维护会话的,由于WebSphere默认未开启URL会话重写,我又不希望对应用服务器的配置提出额外的要求,
因此决定放弃URL重写方式,统一采用Cookie维护会话。因此集成插件做了如下的调整:
    

public String doGet(String url, String token) {
       CloseableHttpResponse response = null;  try {  if (logger.isDebugEnabled()) {
            String message = MessageFormat.format("doGet[request]:\n[{0}]", url); logger.debug(message);
           }
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader(new BasicHeader("Cookie", "JSESSIONID=" + token));//==>①这儿通过Cookie上传会话ID
        httpGet.setConfig(requestConfig);

        response = httpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, Consts.UTF_8); if (logger.isDebugEnabled()) {
            String message = MessageFormat.format("doGet[response]:\n[{0}]", result); logger.debug(message);
        }  return result;
    } catch (IOException e) {  logger.error("doGet error", e);  throw new RuntimeException(e);
    } finally {  try {  if (response != null) {
                response.close();
            }
        } catch (IOException e) {  logger.error("doGet error", e); throw new RuntimeException(e);
        }
    }
}

      本以为这样就可以万事大吉了,可是还是使用Jetty,Tomcat运行集成平台时都是正常的,但是使用WebSphere时还是外甥打灯笼--照旧,依然顽强地一点击被集成组件菜单就弹出到集成平台的登录页面。

Websphere奇葩的会话ID     

     一般应用服务器通过HttpSession.getId()获取的ID和其自动被Cookie中写的JSESSIONID是一致的,可是WebSphere毕竟不是常人,它非常有个性的两者不一致。也就是说你在服务器获取的会话ID和它写到客户端的会话ID是不一致的,而且如果你手工将服务端获取的会话ID放到Cookie中的JSESSIONID中时,服务端无法找到对应的会话!!!!!,我不想让人说我诬陷IBM,有图为证:


图4 WebSphere Cookie的会话ID和服务端获取不一致

    且不说 WebSphere往Cookie中写的一大坨内容究竟有没有必要(tomcat,jetty的cookie都是清清爽爽的),它往Cookie中写的会话ID不是服务器端
通过HttpSession.getId()获取的会话ID,而是头尾都加了东西:头部添加了“0000”,尾部添加了:19vrbkigt(不知道啥用途)
如果要通过Cookie维护
会话,一定要学WebSphere在会话ID前添加“0000”,否则请求发上去就找不到对应的会话了。

       由于Jetty的会话ID为12位,Tomcat的会话32位,而webSphere的会话ID(服务端的)23位,所以我就根据会话ID长度来识别是哪咱类型应用服务器的会话ID
,如果是websphere的就在前面添加0000,代码如下:

/**  * 对{@code token}进行处理:  * <pre>  *     1.was 的token前面需要添加0000:xxx=>0000xxx  *     2.jetty,tomcat,等其它应用服务器直接返回原值.  *     注意:was的token为23位,jetty及tomcat的token分别为12及32位.  * </pre>  * @param token  * @return  */ private static final String getNormToken(String token) {  if (token != null && token.length() == WAS_TOKEN_LENGTH) { return "0000"+token;
  }else{ return token;
  }
}

小结
     


     WebSphere不死,程序灾难未平!

© 著作权归作者所有

stamen

stamen

粉丝 88
博文 28
码字总数 28437
作品 1
厦门
私信 提问
【中间件安全】WebSphere安全加固规范

版权声明:本文由Bypass原创发布,转载请保留出处。欢迎关注我的个人微信公众号:Bypass--,浏览更多精彩文章。 https://blog.csdn.net/qq_23936389/article/details/86150485 【中间件安全】...

Bypass007
2018/12/24
0
0
WebSphere Application Server V7高级安全性加强,第2部分

高级安全性注意事项 简介 第 1 部分 解释了 IBM WebSphere Application Server V6.1 和更高版本在设计时如何考 虑到默认安全性安全原则。目标是在最常见的配置和比较简单的环境中,让这个产品...

wolf_su
2013/06/27
72
0
Hyperic HQ监控IBM WebSphere MQ

IBM公司的WebSphere MQ(MQSeries的前身)是一个信息服务器,使您可以轻松地在不同平台交流信息,整合新的和现有的商业应用。 Hyperic HQ对MQ的支持是作为其管理所有的WebSphere技术的全面解...

liuyifeng
2010/09/10
918
0
Bobby Woolf:从何学习 WebSphere

有大量关于 IBM® WebSphere® 产品的参考资料可供您任意选择学习,并且几乎所有这些参考资料都是完全免费的。这里应该掌握的技巧是知道需要哪些信息以及如何查找信息。 http://www.baisouj...

baisou
2013/09/13
35
0
WebSphere Application Server V7高级安全性加强,第1部分:(下)

考虑对 Web 服务器到 WebSphere Application Server 的 HTTP 链路进行身份验证 WebSphere Application Server Web 服务器插件将来自 Web 服务器的请求转发到目标应用 服务器。在默认情况下,...

wolf_su
2013/06/27
361
0

没有更多内容

加载失败,请刷新页面

加载更多

parseint和isNaN用法

本文转载于:专业的前端网站➭parseint和isNaN用法 <!doctype html><html><head><meta charset="utf-8"><title>无标题文档</title></head><body><script> var a='12'; alert......

前端老手
21分钟前
3
0
Kylin 精确去重在用户行为分析中的妙用

作者:史少锋,Apache Kylin committer & PMC,2019/10/11 在上次文章《如何在 1 秒内做到大数据精准去重》中,我们介绍了 Apache Kylin 为什么要支持大数据集上的精确去重,以及基于 Bitmap...

ApacheKylin
32分钟前
3
0
学习记录(二) es6基本语法(rest参数,模板化,axios模块,拦截器)

日常学习记录 模块化:把一个大文件分成多个小文件,按照一定规范进行拼接 es5写法: 导出:module.exports = 数据 导入:require("路径") /路径未添加后缀名时 //默认添加.js //把路径作为文件名...

Pole丶逐
36分钟前
3
0
以程序员的角度怎么购买一台「性价比高的电视」

前俩天有小伙伴在我的文章下留言,说能否把 【国内电视机都介绍一下】,今天我已在TV端开发多年的程序员的角度。谈谈已程序员的角度如何购买一台性价比高的电视。 国内大的电视机品牌介绍 长...

我们都很努力着
39分钟前
2
0
PhotoShop 色调:理解直方图/RGB通道信息

一、直方图:图表的形式,展示图像像素分布的情况 1.平均值:表示平均亮度 2.标准偏差值:表示亮度值范围内的中间值 3.像素: 表示用于计算直方图的像素总数 4.色阶:显示指针下面的区域亮度...

东方墨天
45分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部