基于 SSL 的 Java SOAP 服务,带有客户端证书
所以我一直在尝试使用 JAX-WS 和 SSL 设置 Java SOAP servlet。我通过 SSL 运行了实际的服务,但我需要它根据客户端证书进行身份验证,现在它正在接受针对它的所有连接。
到目前为止,这是我的代码:
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
System.out.println("yay1");
}
public void checkServerTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
System.out.println("yay2");
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException("Not supported yet.");
}
};
String uri = "http://127.0.0.1:8083/SoapContext/SoapPort";
Object implementor = new Main();
Endpoint endpoint = Endpoint.create(implementor);
SSLContext ssl = SSLContext.getInstance("TLS");
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore store = KeyStore.getInstance("JKS");
store.load(new FileInputStream("serverkeystore"),"123456".toCharArray());
keyFactory.init(store, "123456".toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(store);
ssl.init(keyFactory.getKeyManagers(),
new TrustManager[] { tm }, null);
HttpsConfigurator configurator = new HttpsConfigurator(ssl);
HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(8083), 8083);
httpsServer.setHttpsConfigurator(configurator);
HttpContext httpContext = httpsServer.createContext("/SoapContext/SoapPort");
httpsServer.start();
endpoint.publish(httpContext);
我正在使用此 PHP 代码对其进行测试:
$soapClient = new SoapClient("https://localhost:8083/SoapContext/SoapPort?wsdl", array('local_cert' => "newcert.pem"));
$soapClient->add(array('i' => '1', 'j' => '2'));
不幸的是,当我包含 local_cert 时,它会出错:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://localhost:8083/SoapContext/SoapPort?wsdl' : failed to load external entity "https://localhost:8083/SoapContext/SoapPort?wsdl"
如果我不包含 local_cert,它确实会成功连接,但它永远不会调用我的自定义 TrustManager,所以它接受所有传入的连接。
我做错了什么?谢谢!
So I've been trying to setup a Java SOAP servlet with JAX-WS and SSL. I got the actual service running over SSL, but I need it to authenticate based on the client certificate, and right now it's accepting all connections against it.
Here's my code so far:
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
System.out.println("yay1");
}
public void checkServerTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
System.out.println("yay2");
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException("Not supported yet.");
}
};
String uri = "http://127.0.0.1:8083/SoapContext/SoapPort";
Object implementor = new Main();
Endpoint endpoint = Endpoint.create(implementor);
SSLContext ssl = SSLContext.getInstance("TLS");
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore store = KeyStore.getInstance("JKS");
store.load(new FileInputStream("serverkeystore"),"123456".toCharArray());
keyFactory.init(store, "123456".toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(store);
ssl.init(keyFactory.getKeyManagers(),
new TrustManager[] { tm }, null);
HttpsConfigurator configurator = new HttpsConfigurator(ssl);
HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(8083), 8083);
httpsServer.setHttpsConfigurator(configurator);
HttpContext httpContext = httpsServer.createContext("/SoapContext/SoapPort");
httpsServer.start();
endpoint.publish(httpContext);
And I'm testing it with this PHP code:
$soapClient = new SoapClient("https://localhost:8083/SoapContext/SoapPort?wsdl", array('local_cert' => "newcert.pem"));
$soapClient->add(array('i' => '1', 'j' => '2'));
Unfortunately, it errors out with this when I include the local_cert:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://localhost:8083/SoapContext/SoapPort?wsdl' : failed to load external entity "https://localhost:8083/SoapContext/SoapPort?wsdl"
It does connect successfully if I don't include local_cert, but it never calls my custom TrustManager, so it accepts all incoming connections.
What am I doing wrong? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不了解 PHP,但 Web 服务中的
TrustManager
没有进行任何身份验证。因此,连接不应因客户端身份验证问题而被拒绝。
您在客户端中引用的
new_cert.pem
是否包含私钥?如果不是,那么这可能就是问题所在。
我建议你拿个wireshark来看看通讯情况。
我怀疑您不会看到来自服务器的拒绝。
故障应该发生在您的客户端本地
I do not know PHP but your
TrustManager
in the web service is not doing any authentication.So the connection should not be rejected due to client authentication issues.
Does the
new_cert.pem
you are referencing in your client, contain the private key?If not then this could be the problem.
I suggest you take a wireshark and see the communication.
I suspect you will not see a rejection coming from your server.
The failure should be local on your client