X509 WS-Security using spring-ws, XWS interceptor

2019-07-31 05:46发布

问题:

I am having a hard time with X509 certificate-based WS-Security in WebSphere v7.

Here's a little background: We are using spring-ws in our application, and we allow for UsernameToken profile security or X509 security. The two are implemented using the Xws Security interceptor, which runs off of the Xws Security Framework:

http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html

We implement the security on both the client-side & the server-side, both using the XWSS interceptor. There are two issues:

  1. The javax.xml.crypto class returned from WebSphere for "http://www.w3.org/2001/10/xml-exc-c14n#" or any CanonicalizationMethod is not compatible with XWSS interceptor. We are seeing this error in the message log on the server-side:

12/5/11 17:26:41:098 EST 00000023 XwsSecurityIn W org.springframework.ws.soap.security.AbstractWsSecurityInterceptor handleValidationException Could not validate request: com.sun.xml.wss.XWSSecurityException: javax.xml.crypto.MarshalException: java.security.NoSuchAlgorithmException: class configured for TransformService: com.ibm.xml.crypto.dsig.dom.transform.ExcC14nTransformer not a TransformService; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: javax.xml.crypto.MarshalException: java.security.NoSuchAlgorithmException: class configured for TransformService: com.ibm.xml.crypto.dsig.dom.transform.ExcC14nTransformer not a TransformService

I think the best thing to do here is override which implementation is used for decrypting these types. We do include the xmldsig-1.0.jar in our war file (which gets deployed with the classloader set to parent-last). Does anybody know of a way to overwrite this? I tried specifying "org.jcp.xml.dsig.internal.dom.XMLDSigRI" in the java.security in my runtime environment, but that did not work. We are including the xmldsig-1.0.jar in our application.

This seems like a compatibility issue between IBM's JRE & Sun's JRE. The XWSS interceptor was written by Sun, so they may have taken some things for granted.

  1. We are getting a NullPointerException on the client-side trying to insert the header elements needed to sign the request. We are using xerces for our DOM implementation, but this seems to be along the lines of the SOAPFactory. I tried setting the property "javax.xml.soap.SOAPFactory" to "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl", but that did not seem to fix the issue. Here is the stack trace:

    [12/3/11 13:39:52:560 EST] 00000027 XwsSecurityIn E org.springframework.ws.soap.security.AbstractWsSecurityInterceptor handleSecurementException Could not secure response: java.lang.NullPointerException; nested exception is com.sun.xml.wss.XWSSecurityException: java.lang.NullPointerException org.springframework.ws.soap.security.xwss.XwsSecuritySecurementException: java.lang.NullPointerException; nested exception is com.sun.xml.wss.XWSSecurityException: java.lang.NullPointerException

    ...

    Caused by: com.sun.xml.wss.XWSSecurityException: java.lang.NullPointerException at com.sun.xml.wss.impl.misc.XWSSProcessor2_0Impl.secureOutboundMessage(XWSSProcessor2_0Impl.java:98) at org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor.secureMessage(XwsSecurityInterceptor.java:135) ... 86 more Caused by: java.lang.NullPointerException at com.sun.xml.wss.core.Timestamp.getAsSoapElement(Timestamp.java:265) at com.sun.xml.wss.core.SecurityHeader.insertHeaderBlock(SecurityHeader.java:90) at com.sun.xml.wss.impl.filter.TimestampFilter.process(TimestampFilter.java:149) at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:87) at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:237) at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:162) at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:137) at com.sun.xml.wss.impl.misc.XWSSProcessor2_0Impl.secureOutboundMessage(XWSSProcessor2_0Impl.java:96) ... 87 more

I've tried setting my policy configuration to disable the timestamp, but then I get a NPE on a different element. I don't believe the configuration is to blame, but here it is anyway:

<?xml version="1.0" encoding="UTF-8"?>
<SecurityConfiguration xmlns="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true">
    <Sign includeTimestamp="false">
        <X509Token certificateAlias="1"/>
    </Sign>
</SecurityConfiguration>

I have tested this on JBoss & Jetty, and both worked as expected. Any assistance would be greatly appreciated...

回答1:

After much research, I've found that the XWS Security Interceptor is incompatible with IBM's JRE. I was able to get it to work with UsernameToken profile security, but it will not work with certificate-based security. I have decided to re-write this using the WSS4J interceptor.

For more information, please look at chapter 7.2:

http://static.springsource.org/spring-ws/site/reference/pdf/spring-ws-reference.pdf