Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-4934

JAXRSInvoker and Proxy classes (Spring Security)

    XMLWordPrintableJSON

    Details

    • Estimated Complexity:
      Unknown

      Description

      Hi,

      I am aware of other tickets regarding the proxy invocation issues.

      During development I noticed an exception popping up:
      IllegalArgumentException: object not instance of class

      I narrowed it down to AbstractInvoker.java:performInvocation(Exchange exchange, Object serviceObject, Method m, Object[] paramArray)

      This kept happening whenever I added a @Secured annotation to a rest method. This annotation caused a Spring Security AOP Proxy to be passed to the default Invoker (JAXRSInvoker.java) instead of the original target class. Which is fine.

      The problem (I think) is in the method performInvocation. The serviceObject parameter is a reference to the Proxy and not the target class causing the line:

      return m.invoke(serviceObject, paramArray);
      

      to fail with the above mentioned error.

      I resolved this by extending JAXRSInvoker and registering it via:

      <jaxrs:invoker>
          <bean class="hr.altima.web.security.SpringSecurityInvokerProxy"/>
      </jaxrs:invoker>
      

      and overriding the performInvocation method like so:

      public class SpringSecurityInvokerProxy extends JAXRSInvoker {
      
          @Override
          protected Object performInvocation(Exchange exchange, Object serviceObject, Method m, Object[] paramArray) throws Exception {
              paramArray = insertExchange(m, paramArray, exchange);
      
      
              if (serviceObject instanceof Proxy) {
                  try {
                      return Proxy.getInvocationHandler(serviceObject).invoke(serviceObject, m, paramArray);
                  } catch (Throwable throwable) {
                      throw new Exception("Proxy invocation threw an exception", throwable);
                  }
              } else {
                  return m.invoke(serviceObject, paramArray);
              }
          }
      }
      

      My reasoning is that you want to call the proxied method (security check) and not the target method directly but the call through proxies should be done differently.

      I am not saying this is the correct way to invoke proxies but it works for this situation although I prefer this to be built in the CXF lib.

        Attachments

        1. web-template.zip
          13 kB
          Fran Pregernik
        2. web-template-2.zip
          13 kB
          Fran Pregernik

          Activity

            People

            • Assignee:
              sergey_beryozkin Sergey Beryozkin
              Reporter:
              franpregernik Fran Pregernik
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: