我的情况如下:
服务器端在与CXF-client和Spring-client交互时是正常的(它主要是解密,验证签名,处理请求,签名,加密和最终发送响应)。
代码:
CXF客户:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="inbound-logging" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="outbound-logging" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<jaxws:client id="helloClient" serviceClass="com.example.HelloWorld"
address="http://localhost:8282/HelloWorld">
<jaxws:inInterceptors>
<ref bean="inbound-logging" />
<ref bean="inbound-security" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="outbound-logging" />
<ref bean="outbound-security" />
</jaxws:outInterceptors>
</jaxws:client>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" id="outbound-security">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="user" value="client"/>
<entry key="signaturePropFile" value="config/client-crypto.properties"/>
<entry key="encryptionPropFile" value="config/client-crypto.properties"/>
<entry key="signatureKeyIdentifier" value="DirectReference"/>
<entry key="encryptionUser" value="server"/>
<entry key="passwordCallbackClass" value="org.mydomain.ClientPasswordCallback"/>
<entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionParts" value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
</map>
</constructor-arg>
</bean>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" id="inbound-security">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="signaturePropFile" value="config/client-crypto.properties"/>
<entry key="decryptionPropFile" value="config/client-crypto.properties"/>
<entry key="passwordCallbackClass" value="org.mydomain.CustomPasswordCallback"/>
</map>
</constructor-arg>
</bean>
Spring-WS客户端 - wss-interceptor:
@Bean
public Wss4jSecurityInterceptor wssInterceptor(
@Qualifier("cryptoFactoryBean") CryptoFactoryBean cryptoFactoryBean,
@Qualifier("signValidCryptoFactoryBean") CryptoFactoryBean signValidCryptoFactoryBean) throws Exception {
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
// outgoing securement
interceptor.setSecurementUsername("client");
interceptor.setSecurementPassword("123456");
interceptor.setSecurementSignatureKeyIdentifier("DirectReference");
interceptor.setSecurementActions("Timestamp Signature Encrypt");
interceptor.setSecurementSignatureCrypto(cryptoFactoryBean.getObject());
interceptor.setSecurementSignatureParts(
"{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;" +
"{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"
);
interceptor.setSecurementEncryptionCrypto(cryptoFactoryBean.getObject());
interceptor.setSecurementEncryptionUser("server");
interceptor.setSecurementEncryptionSymAlgorithm("http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
interceptor.setSecurementEncryptionParts(
"{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;" +
"{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"
);
// incoming validation:
interceptor.setValidationActions("Timestamp Signature Encrypt");
interceptor.setValidationDecryptionCrypto(cryptoFactoryBean.getObject());
interceptor.setValidationSignatureCrypto(signValidCryptoFactoryBean.getObject());
return interceptor;
}
记录级别设置为debug。结果如下:
(... - 与加密数据befrore发送相关的日志) 2015-08-09 19:09:45.181 DEBUG WSSecEncrypt:258 - 加密完成。 2015-08-09 19:09:45.182 DEBUG已发送:620 - 已发送请求[SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#} EncryptedData] 2015-08-09 19:09:45.223 DEBUG收到:678 - 收到回复[SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#} EncryptedData]请求[SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#} EncryptedData] 2015-08-09 19:09:45.224 DEBUG Wss4jSecurityInterceptor:562 - 通过操作验证消息[SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#} EncryptedData] [时间戳签名加密] 2015-08-09 19:09:45.225 DEBUG WSSecurityEngine:236 - 输入processSecurityHeader() 2015-08-09 19:09:45.229 WARN Wss4jSecurityInterceptor:281 - 无法验证请求:未找到WS-Security标头 2015-08-09 19:09:45.229 DEBUG Wss4jSecurityInterceptor:288 - 没有异常解析器存在,造成基本的肥皂故障 线程&#34; main&#34;中的例外情况org.springframework.oxm.UnmarshallingFailureException:JAXB解组异常;嵌套异常是javax.xml.bind.UnmarshalException:意外元素(uri:&#34; http://schemas.xmlsoap.org/soap/envelope/&#34;,local:&#34; Fault&#34;)。预期元素是&lt; {} helloRequest&gt;,&lt; {{{}}} helloResponse&gt; 在org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:809) 在org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:730) 在org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62) 在org.springframework.ws.client.core.WebServiceTemplate $ 3.extractData(WebServiceTemplate.java:407) 在org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:596) 在org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537) 在org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:384) 在org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:374) 在client.Main.main(Main.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:497) 在com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) 引起:javax.xml.bind.UnmarshalException:意外元素(uri:&#34; http://example.com&#34;,local:&#34; Fault&#34;)。预期元素是&lt; {} helloRequest&gt;,&lt; {{{}}} helloResponse&gt; at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext $ DefaultRootLoader.childElement(UnmarshallingContext.java:1131) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153) 在com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:229) 在com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:112) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:354) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:337) 在javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:127) 在org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:726) ......还有12个
看起来Spring正在尝试处理响应而不先解密它。
我找到了问题的解决方案。我没有设置密码回调,所以wss4j-interceptor无法解密响应。以下是解决问题的代码:
KeyStoreCallbackHandler keyStoreCallbackHandler = new KeyStoreCallbackHandler();
keyStoreCallbackHandler.setPrivateKeyPassword("123456");
interceptor.setValidationCallbackHandler(keyStoreCallbackHandler);
答案 0 :(得分:0)
您收到对方的肥皂故障。肥皂故障消息未加密,这就是 Wss4jSecurityInterceptor 抱怨ws-security标头的原因。
2015-08-09 19:09:45.229 WARN Wss4jSecurityInterceptor:281 -
**Could not validate request: No WS-Security header found**
似乎消息的处理在它应该正常停止的同时继续进行。 JAXB marshaller抱怨(uri:&#34; http://schemas.xmlsoap.org/soap/envelope/&#34;,local:&#34; Fault&#34;)不是来自上下文。
2015-08-09 19:09:45.229 DEBUG Wss4jSecurityInterceptor:288 -
No exception resolver present, creating basic soap fault
Exception in thread "main"
org.springframework.oxm.UnmarshallingFailureException:
JAXB unmarshalling exception; nested exception is
javax.xml.bind.UnmarshalException: unexpected element
(uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault").
Expected elements are <{}helloRequest>,<{http://example.com}helloResponse>
我会推荐以下内容:
答案 1 :(得分:0)
没有为拦截器定义KeyStoreCallbackHandler - 就是这种情况。初始帖子中的适当代码。