Announcement Announcement Module
Collapse
No announcement yet.
mustUnderstand not understood (Wss4jSecurityInterceptor not wired?) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • mustUnderstand not understood (Wss4jSecurityInterceptor not wired?)

    Hi All,

    This smells alot like a simple configuration problem rooted, no doubt, in my immature knowledge of Spring. But I am stumped and would be most grateful for some guidance.

    Here is the environment:
    • Spring STS 2.7.1 (the project uses Maven and JAXB2)
    • A simple Spring Web Service
    • A simple Spring Web Service client
    And here are the phenomena:
    1. The client and service work fine without any security
    2. After adding UsernameToken validationActions on the server and UsernameToken securementActions on the client, I observe
      • message on the Tomcat Server console: "WARNING: Could not handle mustUnderstand headers" {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security. Returning fault
      • exception "One or more mandatory SOAP header blocks not understood" returned to the client
    Note also that running the client without securement actions works OK. My understanding is that this case should fail with an error denoting that a security header is missing.

    So, I reason that the service side somehow doesn't know that it is supposed to be validating the incoming requests.

    Here are what seem to me to be the pertinent parts of the server and client:

    spring-ws-servlet.xml
    Code:
    <bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
      <property name="validationActions" value="UsernameToken" />
      <property name="validationCallbackHandler" ref="callbackHandler" />
    </bean>
    
    <bean id="callbackHandler" class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
      <property name="users">
        <props>
          <prop key="Bert">Ernie</prop>
          <prop key="Mickey">Mouse</prop>
        </props>
      </property>
    </bean>	
    	 
    <bean name="endpointMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
       <property name="interceptors">
          <list>
            <ref local="wsSecurityInterceptor" />
          </list>
        </property>
    </bean>	
        
    <context:component-scan base-package="com.company.bws" />
    applicationContext.xml
    Code:
    <bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
      <property name="securementActions" value="UsernameToken"/>
      <property name="securementUsername" value="aaa"/>
      <property name="securementPassword" value="bbb"/>
    </bean>
     
    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
      <constructor-arg ref="messageFactory" /> 
       <property name="marshaller" ref="marshaller" /> 
       <property name="unmarshaller" ref="marshaller" />
          
       <property name="messageSender">
                <bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender" />
       </property>
     
       <property name="interceptors">  
         <list>  
           <ref local="wsSecurityInterceptor" />  
         </list>  
      </property>  
     
      <property name="defaultUri" value="http://localhost:8080/mbws/spring-ws" /> 
    </bean>
    A Snippet from the endpoint class
    Code:
    @Endpoint
    
    public class BwsEndpoint 
    {
     @Autowired
     private Bws bwsService;                                                                          // auto-wired reference to the service implementation
    
     public static final String namespaceUri = "http://company.com/bws/schemas";  
    		
     @PayloadRoot(localPart = "StartServerRequest", namespace=namespaceUri)
     @ResponsePayload
    
     public StartServerResponse handleStartServer(@RequestPayload StartServerRequest request) 
     {
       StartServerResponse response = new ObjectFactory().createStartServerResponse();
       response.setPid(bwsService.startServerRequest(request.getStartServerName(), request.getStartFlags(), request.getFromHostName()));
       return response;
     }
    There are 3 Java classes: an interface class, an implementation thereof, and the endpoint class shown above. The latter's bwsService member is a reference to the implementation class.

    I don't know enough to make this judgment, but is it possible that the service's Wss4jSecurityInterceptor is not getting "attached" to the appropriate endpoint?

    Again, I would be most grateful for any light on this matter.

    Thank you.

    -Saul

    P.S. - I wasn't quite sure where to post this. But given my sense that this might be a fundamental error on my part, I thought to put it here before going to the "security" forum.

  • #2
    All,

    FWIW here is the resolution to this matter:

    a. I removed from spring-ws-servlet.xml this bean definition:

    Code:
        <bean name="endpointMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
          <property name="interceptors">
            <list>
              <ref local="wsSecurityInterceptor" />
            </list>
          </property>
        </bean>
    b. I wrapped the bean referenced by wsSecurityInterceptor within an <sws:interceptor> tag, e.g.

    Code:
        <sws:interceptors>
    	<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    	  <property name="validationActions" value="UsernameToken" />
    	  <property name="validationCallbackHandler" ref="callbackHandler" />
    	</bean>
        </sws:interceptors>
    If anyone can explain why these changes fixed the problem, I would be interested.

    Thanks.

    -Saul

    Comment

    Working...
    X