記Weblogic部署BUG(websocket)

將含有websocket的SSM項目部署在Weblogic上面,遇到websocket報錯以下java

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的對象中.web

能夠搜到的相似問題中,都在嘗試將/websocket排除在web.xml中的filter以外,而這邊遇到的項目,這麼作不現實,因此開始分析該bugspring

 

思路:websocket

1.DEBUG獲取到出錯的 filterChain,發現weblogic自行追加了一個fitler,叫TyrusServletFilter,錯誤在這個Filter中發生.session

2.從weblogic的安裝目錄中找到TyrusServletFilter的jar包,引入到IDEA,準備反編譯看源碼app

3.根據上面的報錯,錯誤發生在SecurityModule中的getCurrentUser中,打斷點DEBUG肯定到具體行:socket

上圖是TyrusServletFilter的反編譯代碼,紅線處可看到,進入出錯代碼的條件代理

具體出錯行,很是明瞭的強制轉換,轉換了request.getSession的結果xml

 

4.在該處進行DEBUG(竟然真的能DEBUG),發現正常的時候,getCurrentUser的request參數是一個ServletRequestImpl對象(來自weblogic),而出錯時,request參數是一個SecurityContextHolderAwareRequestWrapper對象,故肯定問題是包裝問題(即包裝器的getSession並無代理好其內部request的getSession方法)對象

 

 

解決方案:

肯定了出錯的包裝類後,要重寫並覆蓋該類,代碼以下:

該包裝類本來並無覆蓋getSession方法,這裏添加覆蓋,加入和TyrusServletFilter中相同的判斷邏輯,

若是符合條件,則就地一層一層拆包裝,拆到ServletRequestImpl爲止.再調用ServletRequestImpl的getSession返回出結果.

若是不符合條件,不作改變.

 

 

這大概是解決該問題的另外一套思路了.

我這裏因爲使用了SpringSecurity,故要作修改的是SecurityContextHolderAwareRequestWrapper

若是使用了別的filter,那麼能夠覆蓋其餘的requestWrapper

固然最簡單的方案仍是在web.xml中將/websocket排除在全部filter外,若是不能夠的話,再按我這個思路作改動

相關文章
相關標籤/搜索