Announcement Announcement Module
Collapse
No announcement yet.
WSS4J: Could not handle mustUnderstand headers Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • WSS4J: Could not handle mustUnderstand headers

    Hello,

    I'm writing web service with Spring and Spring WS Security. And I have the following configuration in my server:
    Code:
    <!-- My applicationContext -->
    <bean id="endpointMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
            <property name="interceptors">
                <list>
                    <ref local="wsServerSecurityInterceptor" />
                </list>
            </property>
        </bean>
    
        <bean id="wsServerSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
            <property name="validationActions" value="Signature"/>
            <property name="validationSignatureCrypto">
                <ref bean="serverCrypto" />
            </property>
        </bean>
    
        <bean id="serverCrypto" class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
            <property name="keyStorePassword" value="mypasswd"/>
            <property name="keyStoreLocation" value="classpath:keystores/server-keystore.jks"/>
        </bean>
    My Java Endpoint:
    Code:
    @Endpoint
    public class MyServiceEndpoint {
        
        private final static String NAMESPACE_URI = "http://www.example.com/service";
    
        @PayloadRoot(localPart = "ServiceRequest", namespace = NAMESPACE_URI)
        @ResponsePayload
        public ServiceResponse handleRequest(@RequestPayload ServiceRequest serviceRequest)
                throws Throwable {
            log.debug(serviceRequest.getTransactionID());
    
            return null;
        }
    }
    But when my client sends a Timestamped SOAP message, my server says:
    Code:
    DEBUG org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping - Looking up endpoint for [{http://www.example.com/service}ServiceRequest]
    DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher - Endpoint mapping [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping@128c73f] maps request to endpoint [public messages.ServiceResponse endpoints.MyServiceEndpoint.handleRequest(messages.ServiceRequest) throws java.lang.Throwable]
    DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher - Handling MustUnderstand header {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security
    WARN  org.springframework.ws.soap.server.SoapMessageDispatcher - Could not handle mustUnderstand headers: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security. Returning fault
    Well, it looks like my client sends a valid message, but service is not understanding message's Security part...

    Can someone help me with this issue?

    P.S. I've found a very similar thread, but it didn't help me

  • #2
    I found the solution! Well, my applicationContext.xml needed the following lines:

    Code:
    <sws:annotation-driven/>
        
    <sws:interceptors>
            <ref bean="wsServerSecurityInterceptor" />
    </sws:interceptors>
    But after adding those lines I got an error saying:
    Code:
    DEBUG org.springframework.ws.soap.server.SoapMessageDispatcher - Endpoint invocation resulted in exception - responding with Fault
    java.lang.IllegalArgumentException: 'jaxbElement' must not be null
    	at org.springframework.util.Assert.notNull(Assert.java:112)
    	at org.springframework.ws.server.endpoint.adapter.method.jaxb.AbstractJaxb2PayloadMethodProcessor.marshalToResponsePayload(AbstractJaxb2PayloadMethodProcessor.java:86)
    	at org.springframework.ws.server.endpoint.adapter.method.jaxb.XmlRootElementPayloadMethodProcessor.handleReturnValue(XmlRootElementPayloadMethodProcessor.java:66)
    	at org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter.handleMethodReturnValue(DefaultMethodEndpointAdapter.java:284)
    	at org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter.invokeInternal(DefaultMethodEndpointAdapter.java:237)
    	at org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter.invoke(AbstractMethodEndpointAdapter.java:53)
    	at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:233)
    As I figured out, you can't return null from your Endpoint's method, so my handleRequest() now looks like this:
    Code:
        @PayloadRoot(localPart = "ServiceRequest", namespace = NAMESPACE_URI)
        @ResponsePayload
        public ServiceResponse handleRequest(@RequestPayload ServiceRequest serviceRequest)
                throws Throwable {
            log.debug(serviceRequest.getTransactionID());
    
            ServiceResponse serviceResponse = new ServiceResponse();
            serviceResponse.setResult(ServiceResponseStatus.SUCCESS);
    
            return serviceResponse;
        }

    Comment

    Working...
    X