Announcement Announcement Module
Collapse
No announcement yet.
No WS-Security header found Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • No WS-Security header found

    Hi,

    I am new to Spring Web Services and am working on an Echo example using Spring-WS 2.0, JAXB2 with Java 1.5. I have the Service side running on Tomcat 6 and can view the WSDL from the browser.

    When I run the following, client side, test :

    @Test
    public void invokeEchoWebService() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setClassesToBeBound(EchoRequest.class, EchoResponse.class);
    WebServiceTemplate template = new WebServiceTemplate();
    template.setMarshaller(marshaller);
    template.setUnmarshaller(marshaller);

    EchoRequest request = new EchoRequest();
    request.message = "hello";

    EchoResponse response = (EchoResponse) template.marshalSendAndReceive("http://localhost:8080/spring-ws-2-demo/", request);

    Assert.assertEquals("hello", response.message);



    I get a “No WS-Security header found” exception:

    org.springframework.ws.soap.client.SoapFaultClient Exception: No WS-Security header found
    at org.springframework.ws.soap.client.core.SoapFaultM essageResolver.resolveFault(SoapFaultMessageResolv er.java:37)
    at org.springframework.ws.client.core.WebServiceTempl ate.handleFault(WebServiceTemplate.java:733)
    at org.springframework.ws.client.core.WebServiceTempl ate.doSendAndReceive(WebServiceTemplate.java:559)
    at org.springframework.ws.client.core.WebServiceTempl ate.sendAndReceive(WebServiceTemplate.java:496)
    at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 343)
    at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 333)


    My Security bean is:

    <bean class="org.springframework.ws.soap.security.wss4j. Wss4jSecurityInterceptor">
    <property name="validationActions" value="UsernameToken"/>
    <property name="validationCallbackHandler">
    Class="org.springframework.ws.soap.security.wss4j. callback.SimplePasswordValidationCallbackHandler">
    <property name="users">
    <props>
    <prop key="ernie">bert</prop>
    </props>

    Any ideas on what the problem might be are very much appreciated.
    Thanks in advance,
    George

  • #2
    I dont see where your WebServiceTemplate use the interceptor.

    How about that ? Inject the one declared in your mapping ?

    Comment


    • #3
      Thanks very much Mada.

      Do I need to update my test class to inject the Wss4jSecurityInterceptor bean so that it can then be passed to
      "template.setInterceptors(interceptors)"?

      Do you know of any simple working examples that use this approach?

      Thanks again,
      George

      Comment


      • #4
        1 - Yes

        By the way your actual test NEED a container available right (tomcat for example).

        A light way to test it is to use Spring ws test api available in Spring ws 2 that release. pelase see the documentation with real examples.

        Comment


        • #5
          Hi Mada,

          I included an @Autowired to get access to the Wss4jSecurityInterceptor bean:

          public class SimpleEchoTest {

          @Autowired
          private Wss4jSecurityInterceptor wss4jSecurityInterceptor;

          private ClientInterceptor[] interceptors = new ClientInterceptor[1];

          @Test
          public void invokeEchoWebService() {
          Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
          marshaller.setClassesToBeBound(EchoRequest.class, EchoResponse.class);
          WebServiceTemplate template = new WebServiceTemplate();
          template.setMarshaller(marshaller);
          template.setUnmarshaller(marshaller);

          interceptors[0] = wss4jSecurityInterceptor;
          System.out.println("*****interceptor zero :" + interceptors[0]);
          template.setInterceptors(interceptors);


          however wss4jSecurityInterceptor is not being injected and I am getting a NullPointerException.

          -------------------------------------------------------
          T E S T S
          -------------------------------------------------------
          Running org.opencredo.demo.SimpleEchoTest
          23-Mar-2011 12:53:49 org.springframework.ws.soap.saaj.SaajSoapMessageFa ctory afterPropertiesSet
          INFO: Creating SAAJ 1.2 MessageFactory
          *****interceptor zero :null
          the message string from the **REQUEST** object :hello
          23-Mar-2011 12:53:49 org.springframework.oxm.jaxb.Jaxb2Marshaller createJaxbContextFromClasses
          INFO: Creating JAXBContext with classes to be bound [class org.opencredo.demo.ws.EchoRequest,class org.opencredo.demo.ws.EchoResponse]
          Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.374 sec <<< FAILURE!
          invokeEchoWebService(org.opencredo.demo.SimpleEcho Test) Time elapsed: 1.234 sec <<< ERROR!
          java.lang.NullPointerException
          at org.springframework.ws.client.core.WebServiceTempl ate.doSendAndReceive(WebServiceTemplate.java:537)

          1. am I correct to assume that :
          @Autowired
          private Wss4jSecurityInterceptor wss4jSecurityInterceptor;

          is sufficient to obtain a reference to the bean?

          2. am I taking the correct approach of creating an array of ClientInterceptor[], to which the wss4jSecurityInterceptor is added, then passing the array to the method template.setInterceptors(interceptors); ?

          3. can you please help to locate an example that passes the Wss4jSecurityInterceptor bean to WebServiceTemplate.setInterceptors.

          Thanks again for your help,
          George

          Comment


          • #6
            @Autowired yourBean is sufficient if you have yourBean available in the applicationContext loaded by spring test.

            But the way that you are trying to do your test tells me that you are using plain junit test, not with the springrunner ?
            if the answer is yes, see the documentation about that.

            If it is no, To be sure could you post the WHOLE test class and every xml file used by your spring test class??

            And You should have something like this in you .xml
            Code:
               <bean id="wsTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
                    <property name="defaultUri" value="${system.endpointUrl}"/>
                    <property name="marshaller" ref="marshaller"/>
                    <property name="unmarshaller" ref="marshaller"/>
                    <property name="interceptors">
                        <list>
                            <bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
                                <property name="secureRequest" value="true"/>
                              (....)
                                    </bean>
                                </property>
                            </bean>
            (...)
            so you could to @Autowired WebServiceTemplate webServiceTemplate without the need to the extra code to inject this marshaller and interceptor.
            Last edited by mada; Mar 23rd, 2011, 02:12 PM.

            Comment


            • #7
              Hi Mada,

              you are correct - I was not using SpringRunner. I have now added SpringRunner and Autowired the Wss4jSecurityInterceptor:

              Code:
              package org.opencredo.demo;
              
              import org.junit.Assert;
              import org.junit.Test;
              import org.junit.runner.RunWith;
              
              import org.opencredo.demo.service.EchoService;
              import org.opencredo.demo.ws.EchoRequest;
              import org.opencredo.demo.ws.EchoResponse;
              import org.springframework.beans.factory.annotation.Autowired;
              import org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor;
              import org.springframework.ws.client.support.interceptor.ClientInterceptor;
              import org.springframework.oxm.jaxb.Jaxb2Marshaller;
              import org.springframework.ws.client.core.WebServiceTemplate;
              
              import org.springframework.test.context.ContextConfiguration;
              import org.springframework.context.ApplicationContext;
              
              import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
              
              @RunWith(SpringJUnit4ClassRunner.class)
              @ContextConfiguration("spring-ws-servlet.xml")
              public class SEchoTest {
               
                  @Autowired
                  private Wss4jSecurityInterceptor wss4jSecurityInterceptor;
                  
                  private ClientInterceptor[] interceptors = new ClientInterceptor[1];
                  
                  @Test
                   public void invokeEchoWebService() {
                      Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
                      marshaller.setClassesToBeBound(EchoRequest.class, EchoResponse.class);
                      WebServiceTemplate template = new WebServiceTemplate();
                      template.setMarshaller(marshaller);
                      template.setUnmarshaller(marshaller);
                      
                      //added 3 lines
                      interceptors[0] = wss4jSecurityInterceptor;
                      System.out.println("*****interceptor zero :" + interceptors[0]);
                      template.setInterceptors(interceptors);
                      
                      EchoRequest request =  new EchoRequest();
                      request.message = "hello";
                      System.out.println("the message string from the **REQUEST** object :" + request.message);
                      
                      EchoResponse response = (EchoResponse) template.marshalSendAndReceive("http://localhost:8080/spring-ws-2-demo/", request);
              
                      Assert.assertEquals("hello", response.message);
                      System.out.println("the message string from the **RESPONSE** object :" + response.message);
              
                  }
              }

              There is no bean matching type org.springframework.ws.soap.security.wss4j.Wss4jSe curityInterceptor.


              Code:
              -------------------------------------------------------
               T E S T S
              -------------------------------------------------------
              Running org.opencredo.demo.SEchoTest
              24-Mar-2011 16:40:24 org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
              INFO: @TestExecutionListeners is not present for class [class org.opencredo.demo.SEchoTest]: using defaults.
              24-Mar-2011 16:40:24 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
              INFO: Loading XML bean definitions from class path resource [org/opencredo/demo/spring-ws-servlet.xml]
              24-Mar-2011 16:40:25 org.springframework.context.support.AbstractApplicationContext prepareRefresh
              INFO: Refreshing [email protected]172: startup date [Thu Mar 24 16:40:25 GMT 2011]; root of
              context hierarchy
              24-Mar-2011 16:40:25 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
              INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5d391d: defining beans [defaultEc
              hoService,echoEndpoint,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotatio
              n.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.ws.ser
              ver.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping#0,org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMe
              thodEndpointMapping#0,org.springframework.ws.server.endpoint.adapter.method.dom.DomPayloadMethodProcessor#0,org.springframework.ws.server.en
              dpoint.adapter.method.SourcePayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.method.jaxb.XmlRootElementPayloadMethodP
              rocessor#0,org.springframework.ws.server.endpoint.adapter.method.jaxb.JaxbElementPayloadMethodProcessor#0,org.springframework.ws.server.endp
              oint.adapter.DefaultMethodEndpointAdapter#0,org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver#0,org.springframework.ws
              .soap.server.endpoint.SoapFaultAnnotationExceptionResolver#0,org.springframework.xml.xsd.SimpleXsdSchema#0,echo,org.springframework.ws.soap.
              server.endpoint.interceptor.DelegatingSmartSoapEndpointInterceptor#0,org.springframework.ws.soap.server.endpoint.interceptor.PayloadRootSmar
              tSoapEndpointInterceptor#0]; root of factory hierarchy
              24-Mar-2011 16:40:26 org.springframework.ws.server.endpoint.interceptor.AbstractValidatingInterceptor afterPropertiesSet
              INFO: Validating using class path resource [echo.xsd]
              24-Mar-2011 16:40:26 org.springframework.test.context.TestContextManager prepareTestInstance
              SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionList
              ener@1b82d69] to prepare test instance [org.opencredo.demo.SEchoTest@ad6513]
              org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.opencredo.demo.SEchoTest': Injection of autowire
              d dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.sp
              ringframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor org.opencredo.demo.SEchoTest.wss4jSecurityInterceptor; nested exception is org
              .springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.ws.soap.security.wss4j.Wss4jSecu
              rityInterceptor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annota
              tions: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
                      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBe
              anPostProcessor.java:285)
              I am using the same spring-ws-servlet.xml for both the service (which is running successfully on Tomcat) and this client test.

              spring-ws-servlet.xml
              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <beans xmlns="http://www.springframework.org/schema/beans"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:sws="http://www.springframework.org/schema/web-services"
                     xmlns:context="http://www.springframework.org/schema/context"
                     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
                     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
              
              
                  <context:component-scan base-package="org.opencredo"/>
                  <sws:annotation-driven/>
              
                  <sws:dynamic-wsdl id="echo" portTypeName="echo" locationUri="http://localhost:8080/spring-ws-2-demo/">
                      <sws:xsd location="classpath:echo.xsd"/>
                  </sws:dynamic-wsdl>
              
                  <sws:interceptors>
                      <bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
                          <property name="validationActions" value="UsernameToken"/>
                          <property name="validationCallbackHandler">
                              <!-- just for testing. for real use cases, use integration with spring security -->
                              <bean class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
                                  <property name="users">
                                      <props>
                                          <prop key="ernie">bert</prop>
                                      </props>
                                  </property>
                              </bean>
                          </property>
                      </bean>
                      <sws:payloadRoot namespaceUri="http://www.opencredo.com/demo" localPart="echoRequest">
                          <bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
                              <property name="schema" value="classpath:echo.xsd"/>
                          </bean>
                      </sws:payloadRoot>
                  </sws:interceptors>
              
              </beans>
              Any pointers?
              Thanks again for your patience.
              ...George

              Comment


              • #8
                Hi Mada,

                something else I forgot to mention - I have successfully run the test by removing the security bean from the sws:interceptor. ie.

                Code:
                <?xml version="1.0" encoding="UTF-8"?>
                <beans xmlns="http://www.springframework.org/schema/beans"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xmlns:sws="http://www.springframework.org/schema/web-services"
                       xmlns:context="http://www.springframework.org/schema/context"
                       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                       http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
                       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
                
                
                    <context:component-scan base-package="org.opencredo"/>
                    <sws:annotation-driven/>
                
                    <sws:dynamic-wsdl id="echo" portTypeName="echo" locationUri="http://localhost:8080/spring-ws-2-demo/">
                        <sws:xsd location="classpath:echo.xsd"/>
                    </sws:dynamic-wsdl>
                
                    <sws:interceptors>
                        <sws:payloadRoot namespaceUri="http://www.opencredo.com/demo" localPart="echoRequest">
                            <bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
                                <property name="schema" value="classpath:echo.xsd"/>
                            </bean>
                        </sws:payloadRoot>
                    </sws:interceptors>
                
                </beans>
                i.e. the client calls the service (hosted on Tomcat) successfully and the text (hello) is echoed which is then displayed by the test. However I am now trying to introduce simple security.

                regards,
                George

                Comment


                • #9
                  Ok you are trying to test the server side not the client side.
                  That is why your webserviceTemplate is not in your xml (i found it weird first).

                  You should use Javacrumbs. google : javacrumbs spring test.
                  It works perfectly without that & ANY tomcat. Just plain junit test with headers and everything.

                  Comment


                  • #10
                    These might helped:

                    Server: Spring-WS 2: WS-Security Using WSS4J
                    Client: Spring WS 2: Client-side WS-Security Using WSS4J

                    Comment

                    Working...
                    X