Reputation: 6198
I have successfuly generated Java classes using wsdl2java. Now I am trying to build a client for accessing the web service. I am using Apache CXF for that. On trying to connect, I get the following error:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: WS Security Error : 181001
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:155)
at $Proxy36.getCustomerOp(Unknown Source)
at com.ievgen.webservices.TestClient4.main(TestClient4.java:87)
Caused by: org.apache.cxf.binding.soap.SoapFault: WS Security Error : 181001
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:46)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:114)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:800)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1592)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1490)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1309)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:622)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:133)
... 2 more
According to what I have found on the web, the 181001 error means that the required authentification block is missing. However, I've configured the username and password as described in documentation: http://cxf.apache.org/docs/ws-secureconversation.html
Here is my code:
package com.ievgen.webservices;
import java.io.File;
import javax.net.ssl.*;
import javax.xml.ws.BindingProvider;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import info.app.catalogservices.schemas.customerquery_1.CustomerQueryType;
import info.app.catalogservices.services.csscatalogservicesinterface_1_0.CustomerError;
import info.app.catalogservices.services.csscatalogservicesinterface_1_0.IntfCatalogServicesService;
import info.app.catalogservices.services.csscatalogservicesinterface_1_0.PortType;
public class TestClient4 {
/**
* @param args
* @throws MalformedURLException
*/
public static void main(String[] args) throws MalformedURLException {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
} };
// TODO Auto-generated method stub
File wsdlFile = new File("WebContent/CatalogServices-1.1.0.wsdl");
URL wsdlUrl = null;
if (wsdlFile.exists()) {
wsdlUrl = wsdlFile.toURL();
} else {
System.out.println("File doesn't exist");
}
System.out.println("WSDL url: " + wsdlUrl);
IntfCatalogServicesService service = new IntfCatalogServicesService(
wsdlUrl);
PortType portType = service.getPortTypeEndpoint();
// This will configure the http conduit dynamically
Client client = ClientProxy.getClient(portType);
client.getRequestContext().put("ws-security.username", "username");
client.getRequestContext().put("ws-security.password", "password");
HTTPConduit http = (HTTPConduit) client.getConduit();
TLSClientParameters tlsParams = new TLSClientParameters();
// set trust manager which trusts to all certificates
tlsParams.setTrustManagers(trustAllCerts);
// The certificate provides another CN that it really is, so disable
// CNcheck
tlsParams.setDisableCNCheck(true);
http.setTlsClientParameters(tlsParams);
String resp;
CustomerQueryType customerQuery = new CustomerQueryType();
customerQuery.setCustomer("0056712120");
java.util.Map<String,Object> requestContext = ((BindingProvider) portType)
.getRequestContext();
//I set username/password twice because I am not sure where to do it better
//I have found different directions in different sources
requestContext.put("ws-security.username", "username");
requestContext.put("ws-security.password", "password");
requestContext
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"https://host:port/Services/intfCatalogServices-service.serviceagent/portTypeEndpoint");
try {
resp = portType.getCustomerOp(customerQuery).toString();
System.out.println(resp);
} catch (CustomerError e) {
e.printStackTrace();
}
}
}
Note: I am able to access the web service using SOAP UI.
Could you please tell me what am I missing here?
EDIT: Here: http://cxf.apache.org/docs/ws-secureconversation.html it is said that it's neccessary to set "ws-security.username.sct:. On the other hand, here: http://cxf.apache.org/docs/ws-securitypolicy.html it is said to set "ws-security.username". I've tried both variants, but neither of them worked for me.
Upvotes: 0
Views: 7310
Reputation: 14607
Does the WSDL you are using have a WS-Policy fragment in there that describes the security requirements? If it doesn't then the WS-SecurityPolicy properties wouldn't be applied as the policies in effect don't mention anything related to security.
If there isn't any security related policies, you will need to drop to hand configuration of the WSS4J interceptors. See http://cxf.apache.org/docs/ws-security.html
Upvotes: 1