Wicket
  1. Wicket
  2. WICKET-5266

Issue with TomcatWebSocketFilter and Spring Security

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 6.9.0
    • Fix Version/s: 6.10.0, 7.0.0-M1
    • Labels:
      None
    • Environment:
      Tomcat

      Description

      Spring Security has a way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

      Before:

      		((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
      

      Should be:

      		while (req instanceof HttpServletRequestWrapper) {
      			req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
      		}
      		((RequestFacade) req).doUpgrade(tomcatWebSocket);
      

      This happens when configuring Spring Security in the web.xml with:

      	<filter>
      		<filter-name>springSecurityFilterChain</filter-name>
      		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      	</filter>
      	<filter-mapping>
      		<filter-name>springSecurityFilterChain</filter-name>
      		<url-pattern>/*</url-pattern>
      	</filter-mapping>
      

        Activity

        Transition Time In Source Status Execution Times Last Executer Last Execution Date
        Open Open Resolved Resolved
        3d 7h 31m 1 Martin Grigorov 11/Jul/13 13:06
        Resolved Resolved Closed Closed
        6h 52m 1 Christophe Levesque 11/Jul/13 19:59
        Christophe Levesque made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Show
        Christophe Levesque added a comment - Saw the change on https://git-wip-us.apache.org/repos/asf?p=wicket.git;a=blob_plain;f=wicket-experimental/wicket-native-websocket/wicket-native-websocket-tomcat/src/main/java/org/apache/wicket/protocol/ws/tomcat7/Tomcat7WebSocketFilter.java;hb=HEAD . Thanks for the quick fix!
        Martin Grigorov made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 7.0.0 [ 12322958 ]
        Fix Version/s 6.10.0 [ 12324643 ]
        Resolution Fixed [ 1 ]
        Hide
        Christophe Levesque added a comment -

        No worries.

        After playing with it, I realized that it's actually the Spring Security module that wraps the request (not Spring Core). I updated the bug description with the relevant part of the web.xml.

        Show
        Christophe Levesque added a comment - No worries. After playing with it, I realized that it's actually the Spring Security module that wraps the request (not Spring Core). I updated the bug description with the relevant part of the web.xml.
        Christophe Levesque made changes -
        Description Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {code}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {code}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Spring Security has a way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {code}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {code}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}

        This happens when configuring Spring Security in the web.xml with:

        {code}
        <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>
        <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
        </filter-mapping>
        {code}
        Christophe Levesque made changes -
        Summary Issue with TomcatWebSocketFilter and Spring Framework Issue with TomcatWebSocketFilter and Spring Security
        Hide
        Martin Grigorov added a comment -

        I still sleep
        It is clear now. Thanks!
        This improvement should be done for all **WebSocketFilters, not just Tomcat's one.

        Show
        Martin Grigorov added a comment - I still sleep It is clear now. Thanks! This improvement should be done for all **WebSocketFilters, not just Tomcat's one.
        Hide
        Christophe Levesque added a comment -

        I'm seeing it with 7.0.37. I don't think this is related to Tomcat though. Spring (and Spring Security) is usually configured as a "listener" in the web.xml and I believe it will wrap the request before it gets to the Wicket servlet.

        From my web.xml:

        	<listener>
        		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        	</listener>
        	<context-param>
        		<param-name>contextConfigLocation</param-name>
        		<param-value>classpath:applicationContext*.xml</param-value>
        	</context-param>
        	<filter>
        		<filter-name>springSecurityFilterChain</filter-name>
        		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        	</filter>
        	<filter-mapping>
        		<filter-name>springSecurityFilterChain</filter-name>
        		<url-pattern>/*</url-pattern>
        	</filter-mapping>
        	<filter>
        		<filter-name>wicket</filter-name>
        		<filter-class>org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter</filter-class>
        		<init-param>
        			<param-name>applicationFactoryClassName</param-name>
        			<param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
        		</init-param>
        	</filter>
        	<filter-mapping>
        		<filter-name>wicket</filter-name>
        		<url-pattern>/*</url-pattern>
        		<dispatcher>REQUEST</dispatcher>
        		<dispatcher>ERROR</dispatcher>
        	</filter-mapping>
        
        Show
        Christophe Levesque added a comment - I'm seeing it with 7.0.37. I don't think this is related to Tomcat though. Spring (and Spring Security) is usually configured as a "listener" in the web.xml and I believe it will wrap the request before it gets to the Wicket servlet. From my web.xml: <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>wicket</filter-name> <filter-class>org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter</filter-class> <init-param> <param-name>applicationFactoryClassName</param-name> <param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value> </init-param> </filter> <filter-mapping> <filter-name>wicket</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
        Hide
        Martin Grigorov added a comment -

        Which version of Tomcat do you use ?
        I haven't seen ClassCastException or other problem so far in this code.

        Show
        Martin Grigorov added a comment - Which version of Tomcat do you use ? I haven't seen ClassCastException or other problem so far in this code.
        Christophe Levesque made changes -
        Description Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {noformat}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {noformat}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {code}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {code}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Christophe Levesque made changes -
        Description Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {code}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {code}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {noformat}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {noformat}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Christophe Levesque made changes -
        Field Original Value New Value
        Description Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:
        {code}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {code}

        Should be:
        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Spring's way of wrapping HTTP servlet requests seems to clash with the code in org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter. The request has to be unwrapped before being cast to RequestFacade.

        Before:

        {code}
        ((RequestFacade) req).doUpgrade(tomcatWebSocket); // Crashes with class cast exception
        {code}

        Should be:

        {code}
        while (req instanceof HttpServletRequestWrapper) {
        req = (HttpServletRequest) ((HttpServletRequestWrapper) req).getRequest();
        }
        ((RequestFacade) req).doUpgrade(tomcatWebSocket);
        {code}
        Christophe Levesque created issue -

          People

          • Assignee:
            Martin Grigorov
            Reporter:
            Christophe Levesque
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development