Announcement Announcement Module
Collapse
No announcement yet.
Using spring ws behind https Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using spring ws behind https

    Hi
    I need to implement a client-server communication using web services and WS-Security.
    I've managed to do that with ease thanks to the spring ws.
    But now, i face a strange problem.
    When I call my ws using http everything is ok, both when using soapui and client app.
    But when I try to use https it fails with this message (stack trace cutted because the post message was to big)

    root cause org.springframework.ws.soap.saaj.SaajSoapEnvelopeE xception: Could not access envelope: Unable to create envelope from given source: ; nested exception is com.sun.xml.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source:
    org.springframework.ws.soap.saaj.SaajSoapMessage.g etSaajVersion(SaajSoapMessage.java:260)
    org.springframework.ws.soap.saaj.SaajSoapMessage.g etImplementation(SaajSoapMessage.java:342)
    org.springframework.ws.soap.saaj.SaajSoapMessage.& lt;init>(SaajSoapMessage.java:117)
    org.springframework.ws.soap.saaj.SaajSoapMessageFa ctory.createWebServiceMessage(SaajSoapMessageFacto ry.java:184)
    ...
    root cause com.sun.xml.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source:
    com.sun.xml.messaging.saaj.soap.EnvelopeFactory.cr eateEnvelope(EnvelopeFactory.java:127)
    ...
    root cause javax.xml.transform.TransformerException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2; The markup in the document preceding the root element must be well-formed.
    org.apache.xalan.transformer.TransformerIdentityIm pl.transform(TransformerIdentityImpl.java:502)
    com.sun.xml.messaging.saaj.util.transform.Efficien tStreamingTransformer.transform(EfficientStreaming Transformer.java:414)
    com.sun.xml.messaging.saaj.soap.EnvelopeFactory.cr eateEnvelope(EnvelopeFactory.java:118) com.sun.xml.messaging.saaj.soap.ver1_1.SOAPPart1_1 Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java :83)
    com.sun.xml.messaging.saaj.soap.SOAPPartImpl.getEn velope(SOAPPartImpl.java:143)
    org.springframework.ws.soap.saaj.support.SaajUtils .getSaajVersion(SaajUtils.java:155)
    org.springframework.ws.soap.saaj.SaajSoapMessage.g etSaajVersion(SaajSoapMessage.java:257)
    org.springframework.ws.soap.saaj.SaajSoapMessage.g etImplementation(SaajSoapMessage.java:342)
    org.springframework.ws.soap.saaj.SaajSoapMessage.& lt;init>(SaajSoapMessage.java:117)
    ...
    root cause org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2; The markup in the document preceding the root element must be well-formed.
    org.apache.xerces.parsers.AbstractSAXParser.parse( AbstractSAXParser.java:1216)
    org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser .parse(SAXParserImpl.java:555)
    org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterI mpl.java:357)
    org.apache.xalan.transformer.TransformerIdentityIm pl.transform(TransformerIdentityImpl.java:485)
    ...

    Server requires mutual authentication and it's set up correctly (I can call other apps and their beans via spring http invoker without problems on https).
    I'm using spring ws 2.0.3 and my config is as follows
    - server side
    web.xml
    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    	version="2.4">
    
    	<servlet>
            <servlet-name>spring-ws</servlet-name>
            <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
            <init-param>
                <param-name>transformWsdlLocations</param-name>
                <param-value>true</param-value>
            </init-param>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>spring-ws</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    
    </web-app>
    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">
    
    	<bean id="placeHolderCoreServer"
    		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    		<property name="ignoreResourceNotFound" value="false" />
    		<property name="locations">
    			<list>
    				<value>classpath://spring-ws.properties</value>
    				<value>file:/${server.external.conf.directory.path}communication/spring/spring-ws-custom.properties
    				</value>
    			</list>
    		</property>
    	</bean>
    
    	<context:component-scan base-package="com.company" />
    
    	<sws:annotation-driven />
    
    	<sws:static-wsdl
    		location="/WEB-INF/classes/com/company/ws/service.wsdl"
    		id="auth" />
    
    
    	<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
    
    	<bean id="messageReceiver"
    		class="org.springframework.ws.soap.server.SoapMessageDispatcher">
    		<property name="endpointAdapters">
    			<bean
    				class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
    				<property name="marshaller" ref="marshaller" />
    				<property name="unmarshaller" ref="marshaller" />
    			</bean>
    		</property>
    		<property name="endpointMappings" ref="endpointMapping" />
    	</bean>
    
    	<bean id="endpointMapping"
    		class="org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping">
    		<property name="messageSenders">
    			<bean
    				class="org.springframework.ws.transport.http.HttpUrlConnectionMessageSender" />
    		</property>
    		<property name="preInterceptors">
    			<bean
    				class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    				<!-- Validation part -->
    				<property name="validationActions" value="Signature Encrypt" />
    				<property name="enableSignatureConfirmation" value="true" />
    				<property name="validationSignatureCrypto" ref="serverCrypto" />
    				<property name="validationDecryptionCrypto" ref="serverCrypto" />
    				<property name="validationCallbackHandler">
    					<bean
    						class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler">
    						<property name="keyStore">
    							<bean
    								class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
    								<property name="password"
    									value="${validation.callback.keystore.password}" />
    							</bean>
    						</property>
    						<property name="privateKeyPassword"
    							value="${validation.callback.privatekey.password}" />
    					</bean>
    				</property>
    				<!-- Sign the response -->
    				<property name="securementActions" value="Signature" />
    				<property name="securementUsername" value="${securement.username}" />
    				<property name="securementPassword" value="${securement.password}" />
    				<property name="securementSignatureCrypto" ref="serverCrypto" />
    				<property name="securementEncryptionCrypto" ref="serverCrypto" />
    				<property name="securementSignatureKeyIdentifier" value="DirectReference" />
    			</bean>
    		</property>
    	</bean>
    
    	<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    		<property name="contextPath" value="com.company.ws.schema" />
    	</bean>
    	<bean id="serverCrypto"
    		class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
    		<property name="keyStorePassword" value="${crypto.keystore.password}" />
    		<property name="keyStoreLocation" value="${crypto.keystore.location}" />
    	</bean>
    
    
    </beans>
    and the client applicationContext.xml part related to WS
    Code:
    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
    
    	<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    		<constructor-arg ref="messageFactory" />
    		<property name="interceptors">
    			<list>
    				<ref local="wsClientSecurityInterceptor" />
    			</list>
    		</property>
    		<property name="marshaller" ref="marshaller" />
    		<property name="unmarshaller" ref="marshaller" />
    		<property name="defaultUri" value="${serv.endpoint.url}" />
    	</bean>
    
    	<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    		<property name="contextPath" value="com.company.ws.schema" />
    	</bean>
    
    	<bean id="wsClientSecurityInterceptor"
    		class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    		<property name="securementActions" value="Signature Encrypt" />
    		<!-- Key alias for signature -->
    		<property name="securementUsername" value="${securement.username}" />
    		<property name="securementPassword" value="${securement.password}" />
    		<property name="securementSignatureCrypto" ref="clientCrypto" />
    		<property name="securementEncryptionCrypto" ref="clientCrypto" />
    		<property name="securementEncryptionUser" value="${securement.encryption.user}" />
    
    		<!-- Validation config -->
    		<property name="validationActions" value="Signature" />
    		<property name="validationSignatureCrypto" ref="clientCrypto" />
    	</bean>
    
    	<bean id="clientCrypto"
    		class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
    		<property name="keyStorePassword" value="${keystore.password}" />
    		<property name="keyStoreLocation" value="${keystore.location}" />
    	</bean>
    Any help will be appreciated

  • #2
    Did you ever resolve this one ?
    I don't have a solution to post yet, but I am seeing this problem myself now.
    No mutual authentication here. Our services just use https, enforced by Spring Security channel security (i.e. requires-channel="https").
    If I switch that to "http" and make web service calls to an "http" endpoint, everything works.
    But if I switch to "https" and make web service calls to the "https" endpoint, well my SOAP UI tests still work, but the same code client side stops working. Reporting:

    Code:
    org.springframework.ws.soap.saaj.SaajSoapEnvelopeException: Could not access envelope: Unable to create envelope from given source: ; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to create envelope from given source:
    org.springframework.ws.soap.saaj.SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:260)
    org.springframework.ws.soap.saaj.SaajSoapMessage.getImplementation(SaajSoapMessage.java:342)
    org.springframework.ws.soap.saaj.SaajSoapMessage.<init>(SaajSoapMessage.java:117)
    org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:184)
    org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:58)
    org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:90)
    org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:86)
    org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
    org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:222)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    
    root cause
    
    net.sf.saxon.trans.XPathException: org.xml.sax.SAXParseException: The markup in the document preceding the root element must be well-formed.
           net.sf.saxon.event.Sender.sendSAXSource(Sender.java:413)
           net.sf.saxon.event.Sender.send(Sender.java:193)
           net.sf.saxon.IdentityTransformer.transform(IdentityTransformer.java:30)
           com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:393)
           com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:102)
           com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl.createEnvelopeFromSource(SOAPPart1_1Impl.java:70)
           com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:122)
           org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion(SaajUtils.java:155)
           org.springframework.ws.soap.saaj.SaajSoapMessage.getSaajVersion(SaajSoapMessage.java:257)
           org.springframework.ws.soap.saaj.SaajSoapMessage.getImplementation(SaajSoapMessage.java:342)
           org.springframework.ws.soap.saaj.SaajSoapMessage.<init>(SaajSoapMessage.java:117)
           org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:184)
           org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:58)
           org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:90)
           org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:86)
           org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
           org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:222)
           org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
           org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
           javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
           javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
           org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
    It's like SSL is adding something to ahead of the XML root element in the inbound request.

    Comment


    • #3
      Hi
      in fact I did. It was a bug in the spring-ws version that I was using (2.0.3).
      See https://jira.springsource.org/browse/SWS-750
      After moving to 2.1.1 everything works fine.

      Comment


      • #4
        Nadir, thank you.

        This product is on 2.0.0, so I'll upgrade it.

        Comment

        Working...
        X