Cross-posting from WSS4J maillist. Thanks, Siarhei
From: Siarhei Kaneuski Sent: Tuesday, January 26, 2010 8:47 PM To: [email protected] Subject: Optional encryption/decryption Hi everyone, I'm working on implementation of CXF service managing user profiles (which may contain sensitive data - credit card number, ID number). There are some profiles containing the sensitive data, and some which don't. Even more, the service can work in mode when no sensitive data will be sent to consumer. Naturally, I'd like to make encryption/decryption optional: * Do not encrypt anything if nothing from encryptionParts is found (on service) * Do not decrypt anything if no encryption key found in WS-Security header (on client) 1. Do not encrypt anything if nothing from encryptionParts is found. When my endpoint is configured in the following way, and I don't put real value to element from encryptionParts, out processing fails: <bean id="serviceOutSecurityInterceptor" class="com org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <constructor-arg> <map> <entry key="action" value="Encrypt" /> <entry key="encryptionPropFile" value="serviceKeystore.properties" /> <entry key="encryptionParts" value="{Element}{http://test.com/sample/service}text" /> <entry key="encryptionUser" value="myClientKey" /> </map> </constructor-arg> </bean> Caused by: org.apache.ws.security.WSSecurityException: General security error (WSEncryptBody/WSSignEnvelope: Element to encrypt/sign not found: {http://test.com/sample/service}text) at org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:505) at org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:459) at org.apache.ws.security.message.WSSecEncrypt.encryptForInternalRef(WSSecEncrypt.java:348) at org.apache.ws.security.message.WSSecEncrypt.build(WSSecEncrypt.java:309) at org.apache.ws.security.action.EncryptionAction.execute(EncryptionAction.java:62) ... 10 more As I see from code, there is no good way to configure WSS4J to ignore missing encryption parts (at least, in WSS4J 1.5.8 which I use). Is that by design? Do you have any suggestions how to handle such situations? I have workaround for it - when service actually has something to encrypt, it puts a encryption part to ThreadLocal, and then my interceptor overriding WSS4JOutInterceptor decides add Encrypt action or not (see attachment). Looks awkward. 2. Do not decrypt anything if no encryption key found in WS-Security header. Client can get response with encrypted parts, but also can get plain message w/o WS-Security header. <bean id="clientInSecurityInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <entry key="action" value="Encrypt" /> <entry key="passwordCallbackRef"> <ref bean="clientCallback" /> </entry> <entry key="decryptionPropFile" value="clientKeystore.properties" /> </map> </constructor-arg> </bean> Fails: org.apache.ws.security.WSSecurityException: An error was discovered processing the <wsse:Security> header at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:219) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236) at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:658) at org.apache.cxf.transport.local.LocalDestination$SynchronousConduit$1$1.run(LocalDestination.java:97) at java.lang.Thread.run(Thread.java:619) Do I understand correctly the behavior is not configurable? WSS4J just looks for security header and fails when nothing found. To workaround that, I had to override WSS4JInInterceptor, and enable Encrypt action (which actually decrypts) when WS-Security header found. Again, it's weird - see attachment (I like most the part accessing SOAPMessage - instantiating SAAJInInterceptor because of lack of access to private method in WSS4JInInterceptor). I'd appreciate if anybody commented: was the behavior described above designed in that way? Are there any good way to implement/workaround that? If not, any suggestions on code attached? Thanks, Siarhei
