我使用启用了MTOM的CXF创建了一个简单的Web服务,它还需要一个时间戳和正文签名,它的配置如下:
@ComponentScan(basePackageClasses={MyService.class})
@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class CXFConfig {
@Autowired
Bus cxfBus;
@Autowired
MyService ws;
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(cxfBus, ws);
endpoint.publish("/MyService");
SOAPBinding binding = (SOAPBinding)endpoint.getBinding();
binding.setMTOMEnabled(true);
Map<String, Object> inProps = new HashMap<String, Object>();
inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE+" "+WSHandlerConstants.TIMESTAMP);
inProps.put(WSHandlerConstants.SIG_PROP_FILE, "wsserver.properties");
WSS4JInInterceptor inc = new WSS4JInInterceptor(inProps);
endpoint.getInInterceptors().add(inc);
return endpoint;
}
}
我的服务界面是:
@WebService
@Component
public interface MyService {
@WebMethod(action="doStuff")
public String doStuff(@WebParam(name="FileData") MTOMMessage message) throws IOException;
}
我的数据类型是:
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class MTOMMessage {
@XmlElement(name = "data", required = true)
@XmlMimeType("text/xml")
protected DataHandler data;
@XmlElement(name = "FileName", required = true)
protected String fileName;
//Getters and Setters
}
然后我有一个客户来称呼它:
public static void main(String[] args) throws IOException {
String xmlLoc = "classpath:com/avum/dasn/ws/test/client-context.xml";
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(xmlLoc);
MyService svc = ctx.getBean(MyService.class);
MTOMMessage msg = new MTOMMessage();
msg.setXmlData(new DataHandler(getURLForTestFile()));
msg.setFileName("TestFileName");
System.out.println(svc.doStuff(msg));
}
client-context.xml如下所示:
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Signature Timestamp"/>
<entry key="signaturePropFile" value="wsclient.properties"/>
<entry key="user" value="ws-security" />
<entry key="passwordCallbackClass" value="com.co.test.PasswordCallbackHandler"/>
</map>
</constructor-arg>
</bean>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
如果我使用的是CXF 3.0.5或更低版本,则可以正常使用。但是,如果我使用3.0.6或更高版本,我会收到“验证邮件时遇到安全错误。”。在服务器上,我收到的消息是“无法验证参考资料”。这是因为服务器没有获得ds:DigestValue元素中出现的相同DigestValue。
我认为它与服务器端代码处理MTOM消息的方式有关,因为如果我禁用MTOM(在客户端和服务器上),那么它工作正常。我不确定如何在以后的CXF版本中使用它。有没有人有任何想法我做错了什么?
由于 大卫