Hi, Thanks for your response and sorry for delay, I was in holidays.
> As far as I remember, POLICY_OVERRIDE is completely supported only in 2.5.2. I've just test with JBoss EAP 6.1 (that use CXF 2.6.6) and got same ClassCastException. > 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? I'm on client side, so I've put a beakpoint in handle(message) method of PolicyOutInterceptor. The neethi policy is retrieved from POLICY_OVERRIDE context property and interceptors seems to be corrects (btw I don't understand why UserNameTokenInterceptor appears twice): org.apache.cxf.ws.security.policy.interceptors.SecurityVerificationOutInterceptor@414b33 org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor@1f9f6a4 org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor@1afc999 but assertions list contains only the one of neethi policy: http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}SupportingTokens-> org.apache.neethi.builders.PolicyContainingPrimitiveAssertion It is this assertion that cannot be casted to Token. I attached the log file with FINEST level. Thanks 2014-02-22 17:06 GMT+01:00 Andrei Shakirin <[email protected]>: > 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 >
