记WEBLOGIC部署BUG(WEBSOCKET)

将含有websocket的SSM项目部署在Weblogic上面,遇到websocket报错如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

java.lang.ClassCastException: org.springframework.session.web.http.SessionReposi

toryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper cannot be cast to

weblogic.servlet.security.internal.SessionSecurityData

at weblogic.servlet.security.internal.SecurityModule.getCurrentUser(Secu

rityModule.java:197)

at weblogic.websocket.tyrus.TyrusServletFilter.doFilter(TyrusServletFilt

er.java:167)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja

va:78)

at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(Abst

ractInstrumentedFilter.java:104)

at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja

va:78)

Truncated. see log file for complete stacktrace

直观看,是类型转换错误,发生在weblogic的对象中.

可以搜到的类似问题中,都在尝试将/websocket排除在web.xml中的filter之外,而这边遇到的项目,这么做不现实,所以开始分析该bug

思路:

1.DEBUG获取到出错的 filterChain,发现weblogic自行追加了一个fitler,叫TyrusServletFilter,错误在这个Filter中发生.

2.从weblogic的安装目录中找到TyrusServletFilter的jar包,引入到IDEA,准备反编译看源码

3.根据上面的报错,错误发生在SecurityModule中的getCurrentUser中,打断点DEBUG确定到具体行:

记WEBLOGIC部署BUG(WEBSOCKET)

上图是TyrusServletFilter的反编译代码,红线处可看到,进入出错代码的条件

记WEBLOGIC部署BUG(WEBSOCKET)

具体出错行,非常明了的强制转换,转换了request.getSession的结果

4.在该处进行DEBUG(居然真的能DEBUG),发现正常的时候,getCurrentUser的request参数是一个ServletRequestImpl对象(来自weblogic),而出错时,request参数是一个SecurityContextHolderAwareRequestWrapper对象,故确定问题是包装问题(即包装器的getSession并没有代理好其内部request的getSession方法)

解决方案:

确定了出错的包装类后,要重写并覆盖该类,代码如下:

记WEBLOGIC部署BUG(WEBSOCKET)

该包装类原本并没有覆盖getSession方法,这里添加覆盖,加入和TyrusServletFilter中相同的判断逻辑,

如果符合条件,则就地一层一层拆包装,拆到ServletRequestImpl为止.再调用ServletRequestImpl的getSession返回出结果.

如果不符合条件,不做改变.

这大概是解决该问题的另一套思路了.

我这里由于使用了SpringSecurity,故要做修改的是SecurityContextHolderAwareRequestWrapper

如果使用了别的filter,那么可以覆盖其他的requestWrapper

当然最简单的方案还是在web.xml中将/websocket排除在所有filter外,如果不可以的话,再按我这个思路做改动

作者: 用户注册了一次

原文:https://www.cnblogs.com/user-for-once/p/10307394.html

相关推荐