Return-Path: Delivered-To: apmail-cxf-users-archive@www.apache.org Received: (qmail 95025 invoked from network); 27 Aug 2008 19:27:10 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 27 Aug 2008 19:27:10 -0000 Received: (qmail 86148 invoked by uid 500); 27 Aug 2008 19:27:07 -0000 Delivered-To: apmail-cxf-users-archive@cxf.apache.org Received: (qmail 86092 invoked by uid 500); 27 Aug 2008 19:27:07 -0000 Mailing-List: contact users-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@cxf.apache.org Delivered-To: mailing list users@cxf.apache.org Received: (qmail 86080 invoked by uid 99); 27 Aug 2008 19:27:07 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 Aug 2008 12:27:07 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [216.94.87.36] (HELO mail.intware.com) (216.94.87.36) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 Aug 2008 19:26:06 +0000 Received: from iwdmail2k3.intware.com (iwdmail2k3 [192.168.3.56]) by mail.intware.com (8.12.10/8.12.10) with ESMTP id m7RJPPBq006818 for ; Wed, 27 Aug 2008 15:25:25 -0400 Received: from 192.168.2.132 ([192.168.2.132]) by iwdmail2k3.intware.com ([192.168.3.56]) with Microsoft Exchange Server HTTP-DAV ; Wed, 27 Aug 2008 19:25:22 +0000 Received: from pod2132 by iwdmail2k3.intware.com; 27 Aug 2008 15:25:35 -0400 Subject: WS-Security/UsernameToken signature with CXF From: Steve Shaw To: users@cxf.apache.org Content-Type: text/plain Content-Transfer-Encoding: 7bit Date: Wed, 27 Aug 2008 15:25:35 -0400 Message-Id: <1219865135.7234.106.camel@pod2132.intware.com> Mime-Version: 1.0 X-Mailer: Evolution 2.22.3.1 X-Virus-Checked: Checked by ClamAV on apache.org Hi all, I've searched the archives and documentation and haven't been able to find a sample or other questions about my particular problem. Short version: I'm having trouble verifying a signature created by signing with the UsernameToken. Longer version: I've got a @WebServiceProvider that looks like this: @WebServiceProvider(portName="helloWorldPort", serviceName="helloWorld") @ServiceMode(value=Service.Mode.MESSAGE) public class SampleWebServiceProvider implements Provider { public SampleWebServiceProvider() { } public SOAPMessage invoke(SOAPMessage soapMessage) { try { return processSOAPMessage(soapMessage); } catch (SOAPException e) { throw new MessageException(e); } catch (RuntimeException e) { throw new MessageException(e); } } public static SOAPMessage processSOAPMessage(SOAPMessage request) throws SOAPException { SOAPMessage response = MessageFactory.newInstance().createMessage(); Name bodyName = SOAPFactory.newInstance().createName("helloWorldResponse"); response.getSOAPBody().addBodyElement(bodyName); SOAPElement respContent = response.getSOAPBody().addChildElement("hello"); respContent.setValue("world"); response.saveChanges(); return response; } It is based on the sample from http://cwiki.apache.org/CXF20DOC/provider-services.html. The spec we're working from specifies that we need UsernameToken authentication with digest password and that we need to sign the body with the UsernameToken. So I set up the endpoint in Spring like this: Since I wasn't able to determine any way to invoke a @WebServiceProvider using the client CXF framework (and any pointers on how to do this would be appreciated), I fell back on using WSS4J to set the authentication and signature parameters. Here is the relevant part of my client code: Document document = soapMessage.getSOAPPart(); WSSecHeader secHeader = new WSSecHeader(); secHeader.insertSecurityHeader(document); // UsernameToken WSSecUsernameToken ut = new WSSecUsernameToken(); ut.setPasswordType(WSConstants.PASSWORD_DIGEST); ut.setUserInfo("pierre", "pierre"); ut.addCreated(); ut.addNonce(); ut.prepare(document); // Signature WSSecSignature sign = new WSSecSignature(); Vector signParts = new Vector(); String name = "Body"; String namespace = "http://schemas.xmlsoap.org/soap/envelope/"; String encMod = "Content"; WSEncryptionPart part = new WSEncryptionPart(name, namespace, encMod); signParts.add(part); if(signParts.size() > 0) { sign.setParts(signParts); } sign.setUsernameToken(ut); sign.setKeyIdentifierType (WSConstants.UT_SIGNING); sign.setSignatureAlgorithm(XMLSignature.ALGO_ID_MAC_HMAC_SHA1); try { sign.build(document, null, secHeader); } catch (WSSecurityException e) { e.printStackTrace(); } ut.prependToHeader(secHeader); The resultant XML is then posted to the web service. Here's the message the web service receives: pierreoNKL/OieFuA0ABiibLJ3/krPkv4=ijPV1heraxFNxCiCiLY9rA==2008-08-27T16:59:06.865Z TnDmYWNSt0r0OQppE2X8cHFBVkI= Q/Km3csM6o2psR2rB5DJAtFeR70= stuff goes here It results in a server warning and stack trace that looks like this: WARNING: Security processing failed (actions mismatch) 27-Aug-2008 12:59:07 PM org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor handleMessage WARNING: org.apache.ws.security.WSSecurityException: An error was discovered processing the header at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:227) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:65) Further notes that may be of interest: 1. The service and client calls work properly if all the security stuff is removed. They still work properly when the UsernameToken authentication is added on its own. It's only when I add the signature code that it no longer works. 2. I'm using maven to build and deploy the project. I'm specifying version 2.0.8 of CXF, which pulls in WSS4J 1.5.4 and xmlsec 1.4.0. 3. I suspect the code might make more sense if there was a client-side CXF method to invoke a WebServiceProvider. There aren't any samples at http://cwiki.apache.org/CXF20DOC/provider-services.html, and all of the samples of WS-Security stuff at http://cwiki.apache.org/CXF20DOC/ws-security.html specify using interceptors and certificates - there's nothing there about signing with UsernameToken. My general question is: what am I doing wrong? Specifically, is there something in my client code that is generating an incorrect signature? Other questions: is there a known problem with this sort of signature? Is there an easy way to debug what's actually going wrong in the code (the initial exception appears to occur in the xmlsec signature code, which is resistant to debugging unless I check out and compile my own copy of it)? Any help is appreciated. -Steve