It works when I retrieve the policy builder from the bus extension. Thanks a lot!
2014-03-04 15:51 GMT+01:00 Andrei Shakirin <[email protected]>: > Hi Christophe, > > The problem, is that you create own Neethi policy builder, that is aware > about CXF assertions: > > Policy wsSecuritypolicy = new PolicyBuilder().getPolicy(inputStream); > > The correct way to do is getting CXF policy builder registered as bus > extension: > InputStream is = this.getClass().getResourceAsStream("/ut-policy.xml"); > org.apache.cxf.ws.policy.PolicyBuilder builder = > bus.getExtension(org.apache.cxf.ws.policy.PolicyBuilder.class); > Policy wsSecuritypolicy = builder.getPolicy(is); > > Working sample is checked in here: > https://github.com/ashakirin/cxf.howtos/tree/master/ws-policy.dynamic > > By the way I guess the mandatory wsp:Policy element is missing in your > UsernameToken assertion, this is a valid one: > <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:UsernameToken> > </wsp:Policy> > </sp:SupportingTokens> > </wsp:All> > </wsp:ExactlyOne> > </wsp:Policy> > > 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 >
