场景说明
项目开发了restful的webservice提供给第三方厂家进行调用,在默认情况下,知道地址就能进行连接,虽然提交的数据可能无法真正的运行到后端,但是还是比较危险。所以需要对访问进行控制。首先想到的就是通过数字证书进行控制。
解决方法
1、生成服务端密钥库并导出证书;
2、将服务端证书导入客户端环境;
3、配置服务端的SSL。
1.1 生成服务端密钥库
-
keytool -genkey -alias wsca9000 -keyalg RSA -keypass changeit -storepass changeit -keystore d:\server.keystore -validity 9000
1.2 导出服务器证书
-
keytool -export -trustcacerts -alias wsca9000 -file d:\server.cer -keystore d:\server.keystore -storepass changeit
2.1 将服务端的证书复制到客户端,并进行导入。
-
keytool -import -trustcacerts -alias wsca9000 -file d:\server.cer -keystore "C:\Program Files\Java\jdk1.7.0_25\jre\lib\security\cacerts" -storepass changeit
3.1 配置服务端的tomcat下server.xml
-
-
maxThreads="150" scheme="https" secure="true"
-
clientAuth="false" sslProtocol="TLS"
-
keystoreFile="D:/server.keystore"
-
keystorePass="changeit"/>
4.1 测试
-
RestfullTester tester = new RestfullTester();
-
String data = "";
-
tester.setUrl("");
-
tester.setDatatype("application/json");
-
tester.setMethod("POST");
-
data = "{\"id\":\"100163331\",\"head\":{\"id\":\"100163331\", \"mainid\":100163331, \"createtime\":\"2013-11-27 11:44:00\", \"paytime\":\"2013-11-27 11:45:00\", \"type\":0, \"status\":2, \"quantity\":1, \"discount\":1389.9, \"total\":0.1, \"vipno\":\"\", \"vipmemo\":\"\", \"storeno\":\"HZ13\"},\"detail\":[{\"id\":\"100163331\", \"productid\":287175, \"productname\":\"221119\", \"price\":1390, \"discount\":1389.9, \"vipdiscount\":0, \"quantity\":1, \"total\":0.1, \"rowno\":1, \"comcode\":\"2143410\", \"counter\":\"03714\", \"memo\":\"ss\", \"storeno\":\"HZ13\"},{\"id\":\"100163331\", \"productid\":287175, \"productname\":\"221119\", \"price\":1390, \"discount\":1389.9, \"vipdiscount\":0, \"quantity\":1, \"total\":0.1, \"rowno\":2, \"comcode\":\"2143410\", \"counter\":\"03714\", \"memo\":\"ss\", \"storeno\":\"HZ13\"}],\"payment\":[{\"id\":\"100163331\", \"type\":\"C0\", \"typeid\":27, \"typename\":\"微信支付\", \"no\":\"\", \"amount\":0.1, \"rowno\":1, \"memo\":null, \"storeno\":\"HZ13\"},{\"id\":\"100163331\", \"type\":\"C0\", \"typeid\":27, \"typename\":\"微信支付\", \"no\":\"\", \"amount\":0.1, \"rowno\":2, \"memo\":null, \"storeno\":\"HZ13\"}]}";
-
tester.setData(data);
-
tester.test();
备注:
RestfullTester 是笔者自己写的测试restful的测试类。
在导入了证书的客户端可以调用成功,并返回数据,
在没有证书的客户端运行抛出异常:
-
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
-
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
-
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1764)
-
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
-
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
-
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
-
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
-
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
-
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
-
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:958)
-
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1203)
-
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1230)
-
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214)
-
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
-
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
-
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
-
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
-
at com.intime.ws.util.RestfullTester.test(RestfullTester.java:65)
-
at com.intime.ws.util.RestfullTester.main(RestfullTester.java:175)
阅读(1575) | 评论(0) | 转发(0) |