Apache CXF Web 服务客户端错误
Apache CXF WebServices Client Error
我有一个使用我拥有的 WSDL 生成的客户端。当我尝试连接到此 WebService 时,出现以下错误:
javax.xml.ws.soap.SOAPFaultException: An error occurred when verifying security for the message.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
托管 WebService 的实际服务器需要包含安全 header 的 SOAP 消息,例如:
<soapenv:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="XXXX">
<o:Username>XXXX</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXX</o:Password>
</o:UsernameToken>
</o:Security>
</soapenv:Header>
如何获取它以及发出请求时生成的 SOAP 消息?这是我在代码中调用 WebService 所做的:
val factory = new org.apache.cxf.jaxws.JaxWsProxyFactoryBean()
factory.setServiceClass(classOf[MyWebService])
// if there is an address, then let's set it!
factory.setAddress("https://my/server/address/MyWebService.svc")
// log incoming and outgoing
factory.getInInterceptors.add(new org.apache.cxf.interceptor.LoggingInInterceptor())
factory.getOutInterceptors.add(new org.apache.cxf.interceptor.LoggingOutInterceptor())
val myServiceClient = factory.create().asInstanceOf[MyWebService]
myServiceClient.myMethod("param")
有什么建议吗?
要使此功能正常运行,您必须执行以下操作:
1. Add the following dependencies (if you have not added it already)
"org.apache.cxf" % "cxf-rt-ws-security" % "3.1.4",
"org.apache.ws.security" % "wss4j" % "1.6.13",
2. In the place where you set information in the client proxy, add the following:
val myWebService = factory.create().asInstanceOf[MyWebService]
val proxy = ClientProxy.getClient(myWebService)
val endpoint = proxy.getEndpoint
import collection.JavaConversions._
val callbackHandler = new CallbackHandler {
override def handle(callbacks: Array[Callback]): Unit = {
val pc = callbacks(0).asInstanceOf[WSPasswordCallback]
pc.setPassword("your password")
}
}
val outProps = Map(
WSHandlerConstants.ACTION -> WSHandlerConstants.USERNAME_TOKEN,
WSHandlerConstants.USER -> "Your user name",
WSHandlerConstants.PASSWORD_TYPE -> WSConstants.PW_TEXT
)
outProps.updated(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler)
val wssOut = new WSS4JOutInterceptor(outProps)
endpoint.getOutInterceptors.add(wssOut)
// set the credentials, timeouts etc
proxy.getRequestContext().put("password", "your password")
我有一个使用我拥有的 WSDL 生成的客户端。当我尝试连接到此 WebService 时,出现以下错误:
javax.xml.ws.soap.SOAPFaultException: An error occurred when verifying security for the message.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
托管 WebService 的实际服务器需要包含安全 header 的 SOAP 消息,例如:
<soapenv:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="XXXX">
<o:Username>XXXX</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXX</o:Password>
</o:UsernameToken>
</o:Security>
</soapenv:Header>
如何获取它以及发出请求时生成的 SOAP 消息?这是我在代码中调用 WebService 所做的:
val factory = new org.apache.cxf.jaxws.JaxWsProxyFactoryBean()
factory.setServiceClass(classOf[MyWebService])
// if there is an address, then let's set it!
factory.setAddress("https://my/server/address/MyWebService.svc")
// log incoming and outgoing
factory.getInInterceptors.add(new org.apache.cxf.interceptor.LoggingInInterceptor())
factory.getOutInterceptors.add(new org.apache.cxf.interceptor.LoggingOutInterceptor())
val myServiceClient = factory.create().asInstanceOf[MyWebService]
myServiceClient.myMethod("param")
有什么建议吗?
要使此功能正常运行,您必须执行以下操作:
1. Add the following dependencies (if you have not added it already)
"org.apache.cxf" % "cxf-rt-ws-security" % "3.1.4",
"org.apache.ws.security" % "wss4j" % "1.6.13",
2. In the place where you set information in the client proxy, add the following:
val myWebService = factory.create().asInstanceOf[MyWebService]
val proxy = ClientProxy.getClient(myWebService)
val endpoint = proxy.getEndpoint
import collection.JavaConversions._
val callbackHandler = new CallbackHandler {
override def handle(callbacks: Array[Callback]): Unit = {
val pc = callbacks(0).asInstanceOf[WSPasswordCallback]
pc.setPassword("your password")
}
}
val outProps = Map(
WSHandlerConstants.ACTION -> WSHandlerConstants.USERNAME_TOKEN,
WSHandlerConstants.USER -> "Your user name",
WSHandlerConstants.PASSWORD_TYPE -> WSConstants.PW_TEXT
)
outProps.updated(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler)
val wssOut = new WSS4JOutInterceptor(outProps)
endpoint.getOutInterceptors.add(wssOut)
// set the credentials, timeouts etc
proxy.getRequestContext().put("password", "your password")