Summary
I have discovered that when the WSDL contains a policy the "interceptor"
method of configuring CXF is never invoked, it trues to use the policy
method with high-level parameters from SecurityConstants parameters.
Is there a way of forcing the policy-based CXF security processing to
include a nonce and timestamp?
Alternatively, is there a way to prevent CXF from going down the
policy-based execution path?
Detail
This is what I have discovered this morning. I downloaded and saved the WSDL
from the Oracle system, and as previously the program setting an explicit
interceptor failed:
Code
Client client = ClientProxy.getClient(port);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());
WSSSecurityProperties properties = new WSSSecurityProperties();
List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
actions.add(WSSConstants.USERNAMETOKEN);
properties.setActions(actions);
properties.setUsernameTokenPasswordType(WSSConstants.UsernameTokenPasswordType.PASSWORD_TEXT);
properties.setTokenUser("user");
properties.setCallbackHandler(new CXFNameCallbackHandler("test1234"));
properties.setAddUsernameTokenNonce(true);
properties.setAddUsernameTokenCreated(true);
WSS4JStaxOutInterceptor ohandler = new WSS4JStaxOutInterceptor(properties);
client.getOutInterceptors().add(ohandler);
Error
Oct 13, 2014 9:30:41 AM
org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean
buildServiceFromWSDL
INFO: Creating Service {http://tempuri.org/}Service10Soap1p2Service from
WSDL:
file:/C:/Users/u08654/work/workspaces/OwsmWEblogicEclipse/TestCallerWithStaticWsdl/wsdl/Service10Soap1p2Soap12HttpPort.wsdl
Invoking whoAmI...
Oct 13, 2014 9:30:42 AM org.apache.cxf.phase.PhaseInterceptorChain
doDefaultLogging
WARNING: Interceptor for
{http://tempuri.org/}Service10Soap1p2Service#{http://tempuri.org/}whoAmI has
thrown exception, unwinding now
org.apache.cxf.ws.policy.PolicyException: No username available
at
org.apache.cxf.ws.security.wss4j.AbstractTokenInterceptor.policyNotAsserted(AbstractTokenInterceptor.java:277)
As it was saying "No Username Created" I thought that it was looking for the
SecurityConstants.USERNAME, and in fact proved that if I add the code for
the "non interceptor" version it does not fail but does not send nonce or
timestamp. This made me think that interceptors were ignored when there is a
policy in the WSDL - so I edited the wsdl
Part of Original WSDL
<definitions name="Service10Soap1p2Service"
targetNamespace="http://tempuri.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://tempuri.org/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"
wsu:Id="wss_username_token_service_policy">
<sp:SupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10 />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>
<types>
...
<binding name="Service10Soap1p2Soap12HttpPortBinding"
type="tns:Service10Soap1p2">
<soap12:binding style="document"
transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
<wsp:PolicyReference
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
URI="#wss_username_token_service_policy"
wsdl:required="false" />
<operation name="echoWithChevrons">
Edited WSDL
<definitions name="Service10Soap1p2Service"
targetNamespace="http://tempuri.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://tempuri.org/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
<types>
...
</portType>
<binding name="Service10Soap1p2Soap12HttpPortBinding"
type="tns:Service10Soap1p2">
<soap12:binding style="document"
transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" />
<operation name="echoWithChevrons">
This now works fine:
Message sent with above code and no policy in WSDL
<?xml version="1.0" encoding="http://www.w3.org/2003/05/soap-envelope"
standalone="no"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soap:mustUnderstand="true">
<wsse:UsernameToken
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="G572ee91e-c4de-4722-be41-7fb9d5c1bfe2">
<wsse:Username>u08654</wsse:Username>
<wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">test1234</wsse:Password>
<wsse:Nonce
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">6g154NEn/nAXwVHQ0m3m5w==
</wsse:Nonce>
<wsu:Created>2014-10-13T09:56:01.062+01:00</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
Now downloading and editing the WSDL is obviously not very desirable to have
to download and edit WSDLs to remove policies and then set up interceptors
for the security.
Ideally there would be a way to force the nonce and timestamp on the
policy-based authentication. In fact I would have thought that it should be
the default following OASIS recommendations
<https://www.oasis-open.org/committees/download.php/13392/wss-v1.0-spec-pr-UsernameTokenProfile-01.htm>
:
/1. It is RECOMMENDED that web service producers reject any
UsernameToken not using both nonce and creation timestamps.
2. It is RECOMMENDED that web service producers provide a timestamp
“freshness” limitation, and that any UsernameToken with “stale” timestamps
be rejected. As a guideline, a value of five minutes can be used as a
minimum to detect, and thus reject, replays.
3. It is RECOMMENDED that used nonces be cached for a period at
least as long as the timestamp freshness limitation period, above, and that
UsernameToken with nonces that have already been used (and are thus in the
cache) be rejected./
If this is not possible is there an easy way to get CXF to ignore the policy
in the WSDL and use the interceptor-based configuration?
Thanks
--
View this message in context:
http://cxf.547215.n5.nabble.com/CXF-client-send-nonce-and-timestamp-tp5749743p5749798.html
Sent from the cxf-user mailing list archive at Nabble.com.