I need to create a WCF Client in Java that should communicate with a WCF server which is using message security with a wsHttpBinding and certificates. For the moment I only need to sign the message (so no encryption needed). I managed to create a Java client to communicate with the server when no message security was implemented, i.e. no certificates where involved. Im not sure how to tell the client which certificate to use but I am able to set both the keystore and truststore for Java. Below is the steps that I have performed,
Creating the service: First I created a WCF server in Visual studio. Here is the wsHttpBinding
<bindings>
<wsHttpBinding>
<binding name ="wsMessage">
<security mode ="Message">
<message clientCredentialType ="None" negotiateServiceCredential="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
The service is signed with the following behaviour configuration:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="False"/>
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceCredentials>
<serviceCertificate findValue="mySubjectName" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
The service is then deployed to Azure. Everything works fine when I create a Web Service Client in Visual Studio so there should be nothing wrong with the service itself.
Creating the client:
1) Downloaded Incubator Netbeans Binaries from the following mirror https://www.apache.org/dyn/closer.cgi/incubator/netbeans/incubating-netbeans/incubating-11.0/incubating-netbeans-11.0-bin.zip
2) I unzipped all files 3) Change jdk version to 1.8 as explained here: How to set the JDK Netbeans runs on? 4) Open Netbeans via incubating-netbeans-11.0-bin\netbeans\bin\netbeans64.exe 5) Create a new web project via File / New Project.../ Java Web Application /. Add GlashFish server, choose Java EE 7 Web. Then finished. 6) Right-click on the project and choose New / Other 7) Enter "Web Service Client" in the filter. Click next. 8) Enter the WSDL in the WSDL URL. 9) Click finish.
I created a new java class and added the following code:
package MyCode;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.xml.ws.BindingProvider;
public class NewClass {
public static void main(String in[]) {
System.out.println("Start");
setTrustStoreAndKeyStores();
MyService.Service1 ss = new MyService.Service1();
MyService.IService1 port = ss.getWSHttpBindingIService1();
BindingProvider bport = (BindingProvider)port;
Map<String, Object> requestContext = bport.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "...");
int a = port.addNumbers(2, 7);
System.out.println("Result: " + a);
}
private static void setTrustStoreAndKeyStores() {
System.setProperty("javax.net.ssl.keyStore", Credentials.keystorePath);
System.setProperty("javax.net.ssl.keyStorePassword", Credentials.keystorePassword);
System.setProperty("javax.net.ssl.trustStore", Credentials.truststorePath);
System.setProperty("javax.net.ssl.trustStorePassword", Credentials.truststorePassword);
File keystore = new File(Credentials.keystorePath);
File truststore = new File(Credentials.truststorePath);
System.out.println("Keystore exists: " + keystore.exists());
System.out.println("Truststore exists: " + truststore.exists());
PrintVariable("javax.net.ssl.trustStore");
PrintVariable("javax.net.ssl.trustStorePassword");
PrintVariable("javax.net.ssl.keyStore");
PrintVariable("javax.net.ssl.keyStorePassword");
}
private static void PrintVariable(String key) {
String value = System.getProperty(key);
if (value == null) {
System.out.println(key + " is not defined");
} else {
System.out.println(key + ": " + value);
}
}
public static class Credentials {
public static String keystorePath = "C:/temp/prxyclient.jks";
public static String keystorePassword = "password";
public static String keystoreFilename = "prxyclient.jks";
public static String keystoreType = "pkcs12";
public static String keystoreAlias = "password";
public static String truststorePath = "C:/Program Files/Java/jdk1.8.0_161/jre/lib/security/cacerts";
public static String truststorePassword = "changeit";
}
}
When I run the code I get the following output
Keystore exists: true
Truststore exists: true
javax.net.ssl.trustStore: C:/Program Files/Java/jdk1.8.0_161/jre/lib/security/cacerts
javax.net.ssl.trustStorePassword: changeit
javax.net.ssl.keyStore: C:/temp/prxyclient.jks
javax.net.ssl.keyStorePassword: password
Followed by the following error:
maj 24, 2019 3:35:15 EM com.sun.xml.wss.impl.misc.DefaultCallbackHandler getDefaultCertificateFromTrustStore
SEVERE: WSS1511: An Error occurred while locating PEER Entity certificate in TrustStore.
maj 24, 2019 3:35:15 EM com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl getCertificate
SEVERE: WSS0216: An Error occurred using CallbackHandler for : EncryptionKeyCallback.AliasX509CertificateRequest
maj 24, 2019 3:35:15 EM com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl getCertificate
SEVERE: WSS0217: An Error occurred using CallbackHandler handle() Method.
java.lang.RuntimeException: An Error occurred while locating PEER Entity certificate in TrustStore
at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultCertificateFromTrustStore(DefaultCallbackHandler.java:1356)
at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.handle(DefaultCallbackHandler.java:599)
at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getCertificate(DefaultSecurityEnvironmentImpl.java:390)
at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:496)
at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:69)
at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:248)
at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:164)
at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:125)
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:359)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:295)
at com.sun.xml.ws.security.secconv.WSSCPlugin.sendRequest(WSSCPlugin.java:373)
at com.sun.xml.ws.security.secconv.WSSCPlugin.process(WSSCPlugin.java:235)
at com.sun.xml.ws.security.secconv.impl.client.SCTokenProviderImpl.issue(SCTokenProviderImpl.java:105)
at com.sun.xml.ws.api.security.trust.client.IssuedTokenManager.getIssuedToken(IssuedTokenManager.java:53)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.invokeSCPlugin(SecurityClientTube.java:458)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:249)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:219)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1106)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1020)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:989)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:847)
at com.sun.xml.ws.client.Stub.process(Stub.java:433)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:62)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:131)
at com.sun.proxy.$Proxy39.addNumbers(Unknown Source)
at MyCode.NewClass.main(NewClass.java:32)
maj 24, 2019 3:35:15 EM com.sun.xml.wss.impl.filter.SignatureFilter process
SEVERE: WSS1413: Error extracting certificate
com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: An Error occurred while locating PEER Entity certificate in TrustStore
at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getCertificate(DefaultSecurityEnvironmentImpl.java:395)
at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:496)
at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:69)
at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:248)
at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:164)
at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:125)
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:359)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:295)
at com.sun.xml.ws.security.secconv.WSSCPlugin.sendRequest(WSSCPlugin.java:373)
at com.sun.xml.ws.security.secconv.WSSCPlugin.process(WSSCPlugin.java:235)
at com.sun.xml.ws.security.secconv.impl.client.SCTokenProviderImpl.issue(SCTokenProviderImpl.java:105)
at com.sun.xml.ws.api.security.trust.client.IssuedTokenManager.getIssuedToken(IssuedTokenManager.java:53)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.invokeSCPlugin(SecurityClientTube.java:458)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:249)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:219)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1106)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1020)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:989)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:847)
at com.sun.xml.ws.client.Stub.process(Stub.java:433)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:62)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:131)
at com.sun.proxy.$Proxy39.addNumbers(Unknown Source)
at MyCode.NewClass.main(NewClass.java:32)
Caused by: java.lang.RuntimeException: An Error occurred while locating PEER Entity certificate in TrustStore
at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultCertificateFromTrustStore(DefaultCallbackHandler.java:1356)
at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.handle(DefaultCallbackHandler.java:599)
at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getCertificate(DefaultSecurityEnvironmentImpl.java:390)
... 25 more
maj 24, 2019 3:35:15 EM com.sun.xml.wss.jaxws.impl.SecurityTubeBase secureOutboundMessage
SEVERE: WSSTUBE0024: Error in Securing Outbound Message.
com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: An Error occurred while locating PEER Entity certificate in TrustStore
at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:502)
at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:69)
at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:248)
at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:164)
at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:125)
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:359)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:295)
at com.sun.xml.ws.security.secconv.WSSCPlugin.sendRequest(WSSCPlugin.java:373)
at com.sun.xml.ws.security.secconv.WSSCPlugin.process(WSSCPlugin.java:235)
at com.sun.xml.ws.security.secconv.impl.client.SCTokenProviderImpl.issue(SCTokenProviderImpl.java:105)
at com.sun.xml.ws.api.security.trust.client.IssuedTokenManager.getIssuedToken(IssuedTokenManager.java:53)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.invokeSCPlugin(SecurityClientTube.java:458)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:249)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:219)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1106)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1020)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:989)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:847)
at com.sun.xml.ws.client.Stub.process(Stub.java:433)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:62)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:131)
at com.sun.proxy.$Proxy39.addNumbers(Unknown Source)
at MyCode.NewClass.main(NewClass.java:32)
Caused by: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: An Error occurred while locating PEER Entity certificate in TrustStore
at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getCertificate(DefaultSecurityEnvironmentImpl.java:395)
at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:496)
... 24 more
Caused by: java.lang.RuntimeException: An Error occurred while locating PEER Entity certificate in TrustStore
at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultCertificateFromTrustStore(DefaultCallbackHandler.java:1356)
at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.handle(DefaultCallbackHandler.java:599)
at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getCertificate(DefaultSecurityEnvironmentImpl.java:390)
... 25 more
maj 24, 2019 3:35:15 EM com.sun.xml.wss.jaxws.impl.SecurityClientTube processClientRequestPacket
SEVERE: WSSTUBE0024: Error in Securing Outbound Message.
com.sun.xml.wss.impl.WssSoapFaultException: Invalid Security Header
at com.sun.xml.wss.impl.SecurableSoapMessage.newSOAPFaultException(SecurableSoapMessage.java:319)
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:365)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:295)
at com.sun.xml.ws.security.secconv.WSSCPlugin.sendRequest(WSSCPlugin.java:373)
at com.sun.xml.ws.security.secconv.WSSCPlugin.process(WSSCPlugin.java:235)
at com.sun.xml.ws.security.secconv.impl.client.SCTokenProviderImpl.issue(SCTokenProviderImpl.java:105)
at com.sun.xml.ws.api.security.trust.client.IssuedTokenManager.getIssuedToken(IssuedTokenManager.java:53)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.invokeSCPlugin(SecurityClientTube.java:458)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:249)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:219)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1106)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1020)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:989)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:847)
at com.sun.xml.ws.client.Stub.process(Stub.java:433)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:62)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:131)
at com.sun.proxy.$Proxy39.addNumbers(Unknown Source)
at MyCode.NewClass.main(NewClass.java:32)
Exception in thread "main" javax.xml.ws.WebServiceException: WSSTUBE0024: Error in Securing Outbound Message.
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:301)
at com.sun.xml.ws.security.secconv.WSSCPlugin.sendRequest(WSSCPlugin.java:373)
at com.sun.xml.ws.security.secconv.WSSCPlugin.process(WSSCPlugin.java:235)
at com.sun.xml.ws.security.secconv.impl.client.SCTokenProviderImpl.issue(SCTokenProviderImpl.java:105)
at com.sun.xml.ws.api.security.trust.client.IssuedTokenManager.getIssuedToken(IssuedTokenManager.java:53)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.invokeSCPlugin(SecurityClientTube.java:458)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:249)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:219)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1106)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:1020)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:989)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:847)
at com.sun.xml.ws.client.Stub.process(Stub.java:433)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:62)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:131)
at com.sun.proxy.$Proxy39.addNumbers(Unknown Source)
at MyCode.NewClass.main(NewClass.java:32)
Caused by: javax.xml.ws.soap.SOAPFaultException: Invalid Security Header
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.getSOAPFaultException(SecurityTubeBase.java:686)
... 19 more
Caused by: com.sun.xml.wss.impl.WssSoapFaultException: Invalid Security Header
at com.sun.xml.wss.impl.SecurableSoapMessage.newSOAPFaultException(SecurableSoapMessage.java:319)
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:365)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:295)
... 18 more
C:\Users\jeslun\AppData\Local\NetBeans\Cache\11.0\executor-snippets\run.xml:111: The following error occurred while executing this line:
C:\Users\jeslun\AppData\Local\NetBeans\Cache\11.0\executor-snippets\run.xml:94: Java returned: 1
BUILD FAILED (total time: 2 seconds)
I think NetBeans is using Metro 2.0 and Glashfish. The error seems to be that it cannot find the correct certificate.
Previously I tried to create a Java Client in Eclipse with both CXF and Axis2 but will probably put that in another thread. I have spend a lot of time trying to get this to work and been reading a lot of articles, blog, etc. But any help is appreciated.