Hi Ramzi,
CXF version 3 has not been tested for interoperable RM+SC with other
stacks, and I'm not surprised if you run into problems. It's unlikely
you'd have a better experience with older versions of CXF, though you
can always give it a try. Certainly the older versions are not going to
support UsesSequenceSTR. I'm glad to take a look at captures of the
message exchanges to see what's going wrong, and when/if I have time
available will get the problems fixed.
I don't think the JDK version makes much difference.
- Dennis
On 07/31/2014 01:20 PM, Yassine, Ramzi wrote:
Thank you Dennis,
I am new to those standards so that was very enlightening. However if you don't
mind from your reply I gathered the following:
1. CXF Version 3 does not mix RM and Secure conversation
2. Based on the standard we need to use UsesSequenceSTR but that is not
supported in CXF
3. We are not configuring CXF right
>From the notes above do you recommend that I NOT use apache CXF at all, or
move down to version 2.7 (maybe?)
This code is going to live in a server that does not use the Oracle (sun) JDK,
I will have to use the IBM JDK, so it is only going to get tougher.
I appreciate your insights,
Thank you,
Ramzi
Thank you,
Ramzi
On Jul 30, 2014, at 7:08 PM, "Dennis Sosnoski" <d...@sosnoski.com> wrote:
Hi Ramzi,
There are issues in combining WS-SecureConversation with WS-ReliableMessaging
in the 3.0.x release. I did some work to support this last year, but it was not
a priority for the group I was working with. Since I didn't have a working
endpoint to test with I didn't pursue it at that time.
The correct way of handling this, according to the WS-I Reliable Secure Profile
(http://www.ws-i.org/Profiles/ReliableSecureProfile-1.0-2010-11-09.html#sec_reliable_msg),
is for the WS-RM CreateSequence to include a wsrm:UsesSequenceSTR element that
identifies the security context token. That's currently not supported. There
might also be a problem in the ordering of the interceptors when using WS-RM in
combination with WS-SC. If you want to send me the full message exchange I can
take a look at where things are going wrong.
Also, I see that you're configuring the WSS4JInInterceptor and
WSS4JOutInterceptor manually, which is something you probably don't want to do
if you're using WS-Policy. You should instead be configuring the security
properties in the JAX-WS client element - see
http://cxf.apache.org/docs/ws-secureconversation.html for an example.
- Dennis
Dennis M. Sosnoski
Java Web Services Consulting <http://www.sosnoski.com/consult.html>
CXF and Web Services Security Training <http://www.sosnoski.com/training.html>
Web Services Jump-Start <http://www.sosnoski.com/jumpstart.html>
On 07/31/2014 09:15 AM, Yassine, Ramzi wrote:
Hey all,
I am working with .Net web services that need to use the WS-SECURITY standards
(WS-Policy, WS-SecureConversation, WS-ReliableMessaging).
My environment
=======================================
- Oracle JSDK Java 6 Update 16
- Apache CXF 3.0.1
- Maven 3.0.4
What is happening?
=======================================
- Generating the java stubs using wsdl2java (apache cxf).
- We have a working certificate (PKCS12) that I know it works as we don't have
an issue using it with jx-ws metro with wsit (we want to move to apache cxf as
the support is lacking in Jx-ws and we have
had other issues with it)
- The current problem is I believe in the reliable messaging part (maybe)
- In calling the .Net service:
We see the create token request
<soap:Header>
<Action
xmlns="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT
</Action>
<MessageID
xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:cc07ca42-8183-4656-a073-98e91642f117
</MessageID>...... This is the request to create the token
With a successful response
....
<s:Body>
<t:RequestSecurityTokenResponse
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType>
<t:RequestedSecurityToken>
<c:SecurityContextToken
u:Id="uuid-7aa72faa-eb08-4fdd-a2d6-8c43fbfdb5d5-5"
xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
<c:Identifier>urn:uuid:07701681-111c-41f7-8cc8-0f9b4211cb36</c:Identifier>
</c:SecurityContextToken>.... The contains the token
and then We send a create sequence
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<Action xmlns="http://www.w3.org/2005/08/addressing">
http://docs.oasis-open.org/ws-rx/wsrm/200702/CreateSequence
</Action>......
Response: (FAIL)
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>urn:uuid:4ff03c67-1b06-4b2c-8248-c0fa9ecaf6fd</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value
xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/sc">a:BadContextToken</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">The message could not be processed.
This is most likely because the action
'http://docs.oasis-open.org/ws-rx/wsrm/200702/CreateSequence' is incorrect or
because the message
contains an invalid or expired security context token or
because there is a mismatch between
bindings. The security context token would be invalid if
the service aborted the channel due to
inactivity. To prevent the service from aborting idle
sessions prematurely increase the Receive
timeout on the service endpoint's binding.
</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
All Soap requests are signed, and we are OK in getting the token however the
second call FAILS. Any help on this is highly appreciated
Here is the client code
=======================================
System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump",
"true");
SpringBusFactory bf = new SpringBusFactory();
try {
File file = new
File(this.getClass().getResource("/cxf.xml").toURI());
URI busFile = file.toURI();
Bus bus = bf.createBus(busFile.toString());
BusFactory.setDefaultBus(bus);
Authentication authentication = new Authentication();
service = authentication.getAuthenticationEndpoint();
((BindingProvider)
service).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"https://someUrl/Authentication.svc"); //removed for privacy
} catch (URISyntaxException e) {
// TODO handle error
e.printStackTrace();
}
The configuration
=======================================
The client properties file
--------------------------
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.file=/keys/ourpkcs12_store
org.apache.ws.security.crypto.merlin.keystore.password=somePasswrord
org.apache.ws.security.crypto.merlin.keystore.type=PKCS12
org.apache.ws.security.crypto.merlin.keystore.alias=someAlias
The CXF file
-------------
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
xmlns:wsa="http://cxf.apache.org/ws/addressing"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://schemas.xmlsoap.org/ws/2005/02/rm/policy
http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd
http://cxf.apache.org/ws/rm/manager
http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd">
<bean id="logInBound"
class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutBound"
class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<jaxws:client name="{http://tempuri.org/}AuthenticationEndpoint"
createdFromAPI="true"
address="https://someWsdlUrl">
<jaxws:properties>
<entry key="ws-security.signature.properties"
value="/client.properties"/>
<entry key="ws-security.callback-handler"
value="OurOwnPasswordCallBackForTheKeyStore"/>
</jaxws:properties>
<jaxws:inInterceptors>
<ref bean="logInBound"/>
<ref bean="inbound-security"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutBound"/>
<ref bean="outbound-security"/>
</jaxws:outInterceptors>
<jaxws:features>
<wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/>
<wsrm-mgr:reliableMessaging>
<wsrm-policy:RMAssertion>
<wsrm-policy:BaseRetransmissionInterval
Milliseconds="10000"/>
<wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>
</wsrm-policy:RMAssertion>
<wsrm-mgr:destinationPolicy>
<wsrm-mgr:acksPolicy intraMessageThreshold="0" />
</wsrm-mgr:destinationPolicy>
</wsrm-mgr:reliableMessaging>
</jaxws:features>
</jaxws:client>
<!-- WSS4JOutInterceptor for signing outbound SOAP -->
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"
id="outbound-security">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature"/>
<entry key="user" value="someUser"/>
<entry key="signatureUser" value="someUser"/>
<entry key="signaturePropFile" value="/client.properties"/>
<entry key="signatureKeyIdentifier" value="X509KeyIdentifier"
/>
<entry key="passwordCallbackClass"
value="OurOwnPasswordCallBackForTheKeyStore.java"/>
<entry key="signatureParts"
value="{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;{Element}{http://www.w3.org/2005/08/addressing}To;{Element}{http://www.w3.org/2005/08/addressing}From;;{Element}{http://www.w3.org/2005/08/addressing}FaultTo;{Element}{http://www.w3.org/2005/08/addressing}ReplyTo;{Element}{http://www.w3.org/2005/08/addressing}MessageID;{Element}{http://www.w3.org/2005/08/addressing}RelatesTo;{Element}{http://www.w3.org/2005/08/addressing}Action"/>
</map>
</constructor-arg>
</bean>
<!-- WSS4JInInterceptor for validating the signature of inbound
SOAP -->
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"
id="inbound-security">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature"/>
<entry key="signaturePropFile" value="/client.properties"/>
<entry key="passwordCallbackClass"
value="OurOwnPasswordCallBackForTheKeyStore.java"/>
</map>
</constructor-arg>
</bean>
</beans>
Trace logs on the .net side
===========================
An error occurred while processing a message. The RM Destination requires the
WS-SecureConversation protocol in the binding. This is likely caused by a
binding mismatch.
The logs and exception
=======================
Jul 30, 2014 2:04:39 PM org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
handleMessage
WARNING: Request does not contain Security header, but it's a fault.
Jul 30, 2014 2:04:39 PM org.apache.cxf.ws.rm.Proxy invoke
SEVERE: Failed to send RM protocol message
{http://docs.oasis-open.org/ws-rx/wsrm/200702}CreateSequence.
org.apache.cxf.binding.soap.SoapFault: The message could not be processed. This
is most likely because the action
'http://docs.oasis-open.org/ws-rx/wsrm/200702/CreateSequence' is incorrect or
because the message contains an invalid or expired security context token or
because there is a mismatch between bindings. The security context token would
be invalid if the service aborted the channel due to inactivity. To prevent the
service from aborting idle sessions prematurely increase the Receive timeout on
the service endpoint's binding.
at
org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor.unmarshalFault(Soap12FaultInInterceptor.java:155)
at
org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor.handleMessage(Soap12FaultInInterceptor.java:66)
at
org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor.handleMessage(Soap12FaultInInterceptor.java:52)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at
org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:140)
at
org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:71)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
at
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1636)
......
Jul 30, 2014 2:04:39 PM org.apache.cxf.phase.PhaseInterceptorChain
doDefaultLogging
org.apache.cxf.interceptor.Fault: Failed to send RM protocol message
{http://docs.oasis-open.org/ws-rx/wsrm/200702}CreateSequence.
at
org.apache.cxf.ws.rm.AbstractRMInterceptor.handleMessage(AbstractRMInterceptor.java:104)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
.....
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.apache.cxf.ws.rm.RMException: Failed to send RM protocol message
{http://docs.oasis-open.org/ws-rx/wsrm/200702}CreateSequence.
at org.apache.cxf.ws.rm.Proxy.invoke(Proxy.java:323)
at org.apache.cxf.ws.rm.Proxy.createSequence(Proxy.java:199)
at org.apache.cxf.ws.rm.RMManager.getSequence(RMManager.java:472)
at
org.apache.cxf.ws.rm.RMCaptureOutInterceptor.handle(RMCaptureOutInterceptor.java:156)
at
org.apache.cxf.ws.rm.AbstractRMInterceptor.handleMessage(AbstractRMInterceptor.java:83)
... 33 more
Caused by: org.apache.cxf.binding.soap.SoapFault: The message could not be
processed. This is most likely because the action
'http://docs.oasis-open.org/ws-rx/wsrm/200702/CreateSequence' is incorrect or
because the message contains an invalid or expired security context token or
because there is a mismatch between bindings. The security context token would
be invalid if the service aborted the channel due to inactivity. To prevent the
service from aborting idle sessions prematurely increase the Receive timeout on
the service endpoint's binding.
at
org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor.unmarshalFault(Soap12FaultInInterceptor.java:155)
at
org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor.handleMessage(Soap12FaultInInterceptor.java:66)
at
org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor.handleMessage(Soap12FaultInInterceptor.java:52)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at
org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:140)
at
org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:71)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
at
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1636)
at
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1525)
at
org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1330)
at
org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:638)
at
org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.ws.rm.Proxy.invoke(Proxy.java:313)
All information in this message is confidential and may be legally privileged.
Only intended recipients are authorized to use it.
All information in this message is confidential and may be legally privileged.
Only intended recipients are authorized to use it.