Hi, The problem is that in CXF with MTOM enabled, when use ws-security signature, it won't sign the MTOM attachment. This may not be a problem when both client and server sides are CXF, but it could be a problem if the other side is .net(WCF), as per the spec, the MTOM attachment should also be the part of the signature.
You can take a look at [1] to get more details. BTW, this issue could get resolved when we upgrade to WSS4J 2.0 [1]http://cxf.547215.n5.nabble.com/Signature-digest-mismatch-when-NET-supplies-MTOM-attachment-td3270961.html ------------- Freeman(Yue) Fang Red Hat, Inc. FuseSource is now part of Red Hat Web: http://fusesource.com | http://www.redhat.com/ Twitter: freemanfang Blog: http://freemanfang.blogspot.com http://blog.sina.com.cn/u/1473905042 weibo: @Freeman小屋 On 2013-5-9, at 下午4:16, Ed Bras wrote: > Hi, > Thanks for the quick reply. > I just did some more tests concerning your Mtom remark below, but I noticed > that it seem to run ok, that is: I don't seem to get the "SOAP 1.1 only > endpoint" error anymore. I also looked on the nightly build server, and it > seem to run ok for the last few days... But I can't even remember changing > anything... strange... Currently I do get another exception, but I am pretty > sure that has to do with the test environment of the server I am connecting > to. The "Soap 1.1." error I got was on the client side already. > > Anyway, I am a bit confused about your mtom remark below, as to me it seems > to work (besides having the exception currently, it works during nightly > build last night and before) and changing it has no effect on my unit tests.. > I see in the debug that it goes out as with the correct mime type " > <mimeType>application/octet-stream</mimeType>". > Why does this not work together? > > > The class DynamicWsaSignaturePartsInterceptor does basically what is > described here: > http://davidvaleri.wordpress.com/2010/09/15/signing-ws-addressing-headers-in-apache-cxf/ > I use this as I am signing some headers that can be null, such that they must > be excluded. > > Sorry, but don't understand what more you want to see of client code, I don't > have think I have more that what I list below. The DeliveryService bean comes > from the cxf-client.xml config and is injected by Spring and is an cxf > axWasClientProxy instance. > > - Ed > > > > >> -----Original Message----- >> From: Freeman Fang [mailto:[email protected]] >> Sent: donderdag 9 mei 2013 9:35 >> To: [email protected] >> Subject: Re: A SOAP 1.2 message is not valid when sent to a SOAP 1.1 >> only endpoint >> >> Hi, >> >> What's the >> DynamicWsaSignaturePartsInterceptor >> like? >> >> Also, could you please append the client code where you send out >> request? >> >> Btw, now MTOM + WS-Security does not work together in CXF, please >> remove <entry key="mtom-enabled" value="true"/> from your >> configuration to see if it helps >> ------------- >> Freeman(Yue) Fang >> >> Red Hat, Inc. >> FuseSource is now part of Red Hat >> Web: http://fusesource.com | http://www.redhat.com/ >> Twitter: freemanfang >> Blog: http://freemanfang.blogspot.com >> http://blog.sina.com.cn/u/1473905042 >> weibo: @Freeman?? >> >> On 2013-5-9, at ??3:15, Ed Bras wrote: >> >>> Hi, >>> I hoped the info below would be enough. Here the cxf client config >> and code of usage. >>> Spring config: I have 3 cxf spring config files, listed below: >>> A) cxf-general.xml that includes the B) cxf-client.xml and C) >>> cxf-tls.xml >>> >>> I hope you can see the cause of this error (see subject mail). If >> more config/code is needed, please let me know. >>> >>> >>> Code usage: >>> ------------------ >>> private final DeliveryService digiDelivery; // injected by >> Spring, contained in client spring config below. >>> private Response deliver(final Request request) { >>> return this.digiDelivery.deliver(request); >>> } >>> >>> // The class DeliveryService is generated: >>> >>> @WebService(targetNamespace = "http://Bla/1.2/", name = >>> "DeliveryService") @XmlSeeAlso({ObjectFactory.class }) >>> @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) public >>> interface DeliveryService { >>> >>> @WebResult(name = "response", targetNamespace = >> "http://Bla/1.2/", partName = "response") >>> @Action(output = >> "http://Bka/1.2/DeliveryService/deliveryResponse", fault = { >> @FaultAction(className = DeliveryServiceFault.class, value = >> "http://Bla/1.2/DeliveryService/delivery/Fault/") }) >>> @WebMethod(action = "http://Bla/1.2/DeliveryService/Request") >>> public Response aanleveren(@WebParam(partName = "request", name = >>> "request", targetNamespace = "http://Bla/services/1.2/") Request >>> request) throws AanleverServiceFault; } >>> ------------------ >>> >>> >>> >>> A) CXF-general.xml: >>> ------------------ >>> <import resource="cxf-tls.xml" /> >>> <import resource="cxf-client.xml" /> >>> >>> <!-- General CXF config: >>> 1) http://cxf.apache.org/docs/configuration.html >>> --> >>> <cxf:bus> >>> <cxf:features> >>> <cxf:logging/> >>> >>> <policy:policies/> >>> >>> <!-- WS-addressing required, see 2) --> >>> <wsa:addressing/> <!-- see: >> http://en.wikipedia.org/wiki/WS-Addressing --> >>> </cxf:features> >>> </cxf:bus> >>> ------------------ >>> >>> >>> >>> B) CXF-tls.xml: >>> ---------------------- >>> <http:conduit >> name="{http://bla/1.2/}AanleverService_V1_2Port.http-conduit"> >>> <http:tlsClientParameters> >>> >>> <!-- "keyPassword" is the password to access/retrieve >> the private key in the key store it self --> >>> <sec:keyManagers >> keyPassword="${tls.keystore.private.key.pwd}" > >>> <!-- The keystore that contains our private key to >> encrypt send data (1 key only) --> >>> <sec:keyStore >> resource="${tls.keystore.private}" >> password="${tls.keystore.private.pwd}" /> >>> </sec:keyManagers> >>> >>> <sec:trustManagers> >>> <!-- This list of certificates that is used to decide >> whether or not to trust certificates --> >>> <sec:keyStore >> resource="${tls.keystore.trusted}" >> password="${tls.keystore.trusted.pwd}"/> >>> </sec:trustManagers> >>> >>> <sec:cipherSuitesFilter> >>> <sec:include>.*_EXPORT_.*</sec:include> >>> <sec:include>.*_EXPORT1024_.*</sec:include> >>> <sec:include>.*_WITH_DES_.*</sec:include> >>> <sec:include>.*_WITH_AES_.*</sec:include> >>> <sec:include>.*_WITH_NULL_.*</sec:include> >>> <sec:exclude>.*_DH_anon_.*</sec:exclude> >>> </sec:cipherSuitesFilter> >>> </http:tlsClientParameters> >>> </http:conduit> >>> ---------------------- >>> >>> >>> >>> C) CXF client spring config (don't own the server side): >>> ---------------------- >>> <jaxws:client id="digiDelivery" serviceClass="DeliverService" >> address="${ deliver.url}"> >>> <jaxws:inInterceptors> >>> <ref bean="SigningInterceptorIn"/> >>> <ref bean="wsaSignaturePartsInterceptor"/> >>> </jaxws:inInterceptors> >>> >>> <jaxws:outInterceptors> >>> <ref bean="SigningInterceptorOut"/> >>> <ref bean="wsaSignaturePartsInterceptor"/> >>> </jaxws:outInterceptors> >>> >>> <jaxws:properties> >>> <entry key="mtom-enabled" value="true"/> >>> <entry key="signatureParts" >> value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401- >> wss-wssecurity-utility-1.0.xsd}Timestamp; >>> >> {Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/> >>> </jaxws:properties> >>> >>> <!--Tried this, but had no effect: jaxws:binding> >>> <soap:soapBinding version="1.1"/> >>> </jaxws:binding--> >>> </jaxws:client> >>> >>> <!-- It will dynamically set the WSA signing parts if required, >> depending if they contain any value. >>> See the class for details --> >>> <bean id="wsaSignaturePartsInterceptor" >> class="DynamicWsaSignaturePartsInterceptor"/> >>> <!-- Required to Sign an outgoing message. --> >>> <bean id="SigningInterceptorOut" >> class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> >>> <constructor-arg> >>> <map> >>> <entry key="action" value="Timestamp Signature"/> >>> <entry key="timeToLive" value="300" /> >>> <entry key="user" >>> value="${deliver.keystore.private.sign.key.alias}"/> >>> >>> <!-- Used to retrieve the passwords of an alias. --> >>> <entry key="passwordCallbackRef" >>> value-ref="pwCallback"/> >>> >>> <!-- Required to send the signature certificate a >> long with the message --> >>> <entry key="signatureKeyIdentifier" >>> value="DirectReference" /> >>> >>> <!-- A reference to the Crypto security >> properties --> >>> <entry key="signaturePropRefId" >> value="cryptoProperties"/> >>> <entry key="cryptoProperties" value- >> ref="cryptoProperties"/> >>> </map> >>> </constructor-arg> >>> </bean> >>> >>> <!-- Required to validate an incoming signed message. --> >>> <bean id="SigningInterceptorIn" >> class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> >>> <constructor-arg> >>> <map> >>> <entry key="action" value="Timestamp Signature"/> >>> <entry key="signaturePropRefId" >> value="cryptoProperties"/> >>> <entry key="cryptoProperties" value- >> ref="cryptoProperties"/> >>> </map> >>> </constructor-arg> >>> </bean> >>> >>> <!-- A callback that returns the keystore password of an alias. - >> -> >>> <bean id="pwCallback" class="ClientKeystorePasswordCallback"> >>> <property name="passwords"> >>> <util:map key-type="java.lang.String" value- >> type="java.lang.String"> >>> <entry key="${deliver.keystore.private.sign.key.alias}" >> value="${deliver.keystore.private.sign.key.pwd}"/> >>> </util:map> >>> </property> >>> </bean> >>> >>> <!-- Ref: >>> 1) http://ws.apache.org/wss4j/config.html >>> 2) https://sites.google.com/site/ddmwsst/ws-security-impl >> --> >>> <util:properties id="cryptoProperties"> >>> <!-- The private keystore info to sign the message --> >>> <prop >> key="org.apache.ws.security.crypto.merlin.keystore.file">${deliver.keys >> tore.private}</prop> >>> <prop >> key="org.apache.ws.security.crypto.merlin.keystore.password">${deliver. >> keystore.private.pwd}</prop> >>> <!-- The trusted keystore info for unsigning received messages -- >>> >>> <prop >> key="org.apache.ws.security.crypto.merlin.truststore.file">${deliver.ke >> ystore.trusted}</prop> >>> <prop >> key="org.apache.ws.security.crypto.merlin.truststore.password">${delive >> r.keystore.trusted.pwd}</prop> >>> </util:properties> >>> >>> ---------------------- >>> >>> >>>> -----Original Message----- >>>> From: Freeman Fang [mailto:[email protected]] >>>> Sent: woensdag 8 mei 2013 5:00 >>>> To: [email protected] >>>> Subject: Re: A SOAP 1.2 message is not valid when sent to a SOAP 1.1 >>>> only endpoint >>>> >>>> Hi, >>>> >>>> You need append your client side configuration and code so that we >>>> can take a look >>>> ------------- >>>> Freeman(Yue) Fang >>>> >>>> Red Hat, Inc. >>>> FuseSource is now part of Red Hat >>>> Web: http://fusesource.com | http://www.redhat.com/ >>>> Twitter: freemanfang >>>> Blog: http://freemanfang.blogspot.com >>>> http://blog.sina.com.cn/u/1473905042 >>>> weibo: @Freeman?? >>>> >>>> On 2013-5-8, at ??2:20, Ed Bras wrote: >>>> >>>>> Hi All, >>>>> I don't know what I changed anymore :(... But I have ended up with >>>>> this exception which I don't seem to solve: >>>>> --- >>>>> Caused by: javax.xml.ws.soap.SOAPFaultException: A SOAP 1.2 message >>>> is >>>>> not valid when sent to a SOAP 1.1 only endpoint. >>>>> --- >>>>> >>>>> I am using CXF 2.7.4 and have the classes generated from the wsdl. >> I >>>>> am using the MTOM and WSS4JOutInterceptor for signing outgoing >>>> messages. >>>>> >>>>> The wsdl contains things like: >>>>> ---- >>>>> <wsdl:definitions ... xmlns:soap11="http ... > <soap11:binding >>>>> <soap11:operation soap11:address >>>>> ---- >>>>> >>>>> So that all sound like soap 1.1, but somehow soap 1.2 is being used >>>> in >>>>> the client for the created message. I have added this in my jaxws >>>>> client config, but it had no effect. >>>>> ---- >>>>> <jaxws:binding> >>>>> <soap:soapBinding version="1.1"/> </jaxws:binding> >>>>> ---- >>>>> >>>>> Why does CXF try to use soap 1.2 at all? >>>>> >>>>> Please some advice on how to solve this? >>>>> - Ed >>>>> >>> >>> > >
