Hi,

As far as I remember, POLICY_OVERRIDE is completely supported only in 2.5.2. 
Before this version the property was not checked for some of chains (server in).
Your error message says that UsernameToken assertion was not created by CXF 
UsernameTokenBuilder.
Could you set breakpoint in PolicyInInterceptor and PolicyOutInterceptor and 
check is your policy really applied?

Regards,
Andrei.

> -----Original Message-----
> From: Christophe Domas [mailto:[email protected]]
> Sent: Freitag, 21. Februar 2014 16:41
> To: [email protected]
> Subject: dynamic ws-policy in message context -> java.lang.ClassCastException:
> org.apache.neethi.builders.PrimitiveAssertion cannot be cast to
> org.apache.cxf.ws.security.policy.model.UsernameToken
> 
> Hi,
> 
> I'm developing a SOAP web service *client* hosted in jboss EAP 6.0.1 (CXF
> 2.4.6).
> 
> The service side needs a UserNameToken header but no policy have been
> declared in wsdl.
> 
> I played with WSS4JOutInterceptor but it is a little bit intrusive.
> I didn't found any cxf jax-ws handler for wss4j so I started to try to add 
> this
> header with ws-policy.
> 
> If I modify the wsdl to add the policy, it works:
> 
>    - declare the policy in wsdl:
> 
>     <wsp:Policy wsu:Id="UsernameToken" xmlns:wsu="
> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
> 1.0.xsd
> "
>         xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"; xmlns:sp="
> http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702";>
>         <wsp:ExactlyOne>
>             <wsp:All>
>                 <sp:SupportingTokens>
>                     <wsp:Policy>
>                         <sp:UsernameToken
>                             sp:IncludeToken="
> http://docs.oasis-open.org/ws-sx/ws-
> securitypolicy/200702/IncludeToken/AlwaysToRecipient"
> />
>                     </wsp:Policy>
>                 </sp:SupportingTokens>
>             </wsp:All>
>         </wsp:ExactlyOne>
>     </wsp:Policy>
> 
> 
>    - use the policy in the same wsdl:
> 
>     <wsdl:binding name="TestServiceSOAP" type="tns:TestService">
>         <wsp:PolicyReference xmlns:wsp="
> http://schemas.xmlsoap.org/ws/2004/09/policy"; URI="#UsernameToken" />
>         <soap:binding style="document" transport="
> http://schemas.xmlsoap.org/soap/http"; />
>         <wsdl:operation name="sayHello">
> 
> 
>    - result is what I expect:
> 
> <soap:Envelope
> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";><soap:Header><wss
> e:Security
> soap:mustUnderstand="1" xmlns:wsse="
> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
> 1.0.xsd"><wsse:UsernameToken
> xmlns:wsu="
> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
> 1.0.xsd"
> wsu:Id="UsernameToken-
> 1"><wsse:Username>testUserName</wsse:Username><wsse:Password
> Type="
> http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-
> profile-
> 1.0#PasswordText">testPassword</wsse:Password></wsse:UsernameToken></
> wsse:Security></soap:Header><soap:Body><ns2:sayHello
> xmlns:ns2="http://www.natixis.com/midsav/wsdl/TestService/
> "><message>hello</message></ns2:sayHello></soap:Body></soap:Envelope>
> 
> 
> But in real life, I cannot modify the wsdl because I'm on client side.
> So I tried to dynamically add the the policy as shortly described in
> http://cxf.apache.org/using-ws-policy-in-cxf-projects.html
> 
> I put the xml ws-policy in a file, load it with neethi and passed the policy 
> to CXF
> stack with PolicyConstants.POLICY_OVERRIDE:
> 
>     @WebServiceRef
>     private TestServiceClient testService;
> 
>     public String testWs() {
> 
>         TestService port = testService.getTestServiceSOAP();
> 
>         // load token policy
>         InputStream inputStream =
> 
> Thread.currentThread().getContextClassLoader().getResourceAsStream("userna
> me-token-ws-policy.xml");
>         Policy wsSecuritypolicy = new
> PolicyBuilder().getPolicy(inputStream);
> 
>         Map<String, Object> requestContext = ((BindingProvider)
> port).getRequestContext();
>         requestContext.put(SecurityConstants.USERNAME, "testUserName");
>         requestContext.put(SecurityConstants.PASSWORD, "testPassword");
>         requestContext.put(PolicyConstants.POLICY_OVERRIDE,
> wsSecuritypolicy);
> 
>         return port.sayHello("hello");
> 
> The policy seems to be well charged by the policy interceptor but it generate 
> a
> ClassCastException:
> 
> Caused by: java.lang.ClassCastException:
> org.apache.neethi.builders.PrimitiveAssertion cannot be cast to
> org.apache.cxf.ws.security.policy.model.UsernameToken
>  at
> org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor.assertUsernameT
> okens(UsernameTokenInterceptor.java:245)
> [cxf-rt-ws-security-2.4.9-redhat-2.jar:2.4.9-redhat-2]
>  at
> org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor.addUsernameTok
> en(UsernameTokenInterceptor.java:264)
> [cxf-rt-ws-security-2.4.9-redhat-2.jar:2.4.9-redhat-2]
>  at
> org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor.handleMessage(U
> sernameTokenInterceptor.java:112)
> [cxf-rt-ws-security-2.4.9-redhat-2.jar:2.4.9-redhat-2]
>  at
> org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor.handleMessage(U
> sernameTokenInterceptor.java:76)
> [cxf-rt-ws-security-2.4.9-redhat-2.jar:2.4.9-redhat-2]
>  at
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChai
> n.java:263)
> [cxf-api-2.4.9-redhat-2.jar:2.4.9-redhat-2]
>  at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
> [cxf-rt-core-2.4.9-redhat-2.jar:2.4.9-redhat-2]
>  at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:461)
> [cxf-rt-core-2.4.9-redhat-2.jar:2.4.9-redhat-2]
> 
> 
> The cast is made on made on UsernameTokenInterceptor:
> 
>     private UsernameToken assertUsernameTokens(SoapMessage message,
> WSUsernameTokenPrincipal princ) {
>         AssertionInfoMap aim = message.get(AssertionInfoMap.class);
>         Collection<AssertionInfo> ais =
> aim.getAssertionInfo(SP12Constants.USERNAME_TOKEN);
>         UsernameToken tok = null;
>         for (AssertionInfo ai : ais) {
>             *tok = (UsernameToken)ai.getAssertion(); <- cast*
> 
> The ai.getAssesrtion() returns a
> org.apache.neethi.builders.PrimitiveAssertion instead of
> org.apache.cxf.ws.security.policy.model.UsernameToken.
> 
> What I have done wrong? I search a lot for samples with
> PolicyConstants.POLICY_OVERRIDE but did not find anything.
> 
> Best regards,
> 
> Christophe

Reply via email to