接上篇:http://guojuanjun.blog.51cto.com/277646/1423392
我们提到过远程对象的调用是通过网络通信的方式进行远程对象方法的调用。既然是网络通信,自然会提到安全问题。如何给远程对象的通信加上安全呢?
奥秘依在UnicastRemoteObject类中,其中一个构造方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /** * Creates and exports a new UnicastRemoteObject object using the * particular supplied port and socket factories. * @param port the port number on which the remote object receives calls * (if port is zero, an anonymous port is chosen) * @param csf the client-side socket factory for making calls to the * remote object * @param ssf the server-side socket factory for receiving remote calls * @throws RemoteException if failed to export object * @since 1.2 */ protected UnicastRemoteObject( int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { this .port = port; this .csf = csf; this .ssf = ssf; exportObject((Remote) this , port, csf, ssf); } |
RMIServerSocketFactory对象负责服务端ServerSocket创建。如上篇所说尽,ServerSocket该接收远程方法调用信息。
RMIClientSocketFactory对象负责客户端Socket的创建,通过该Socket向远程对象发起方法调用。显然RMIClientSocketFactory对象工作在客户端,必然需要实现Serializable接口,并伴随远程对象的存根序列化到客户端.
JDK提供了支持SSL的一对RMIServerSocketFactory,RMIClientSocketFactory:
1 | public class SslRMIServerSocketFactory implements RMIServerSocketFactory |
1 2 | public class SslRMIClientSocketFactory implements RMIClientSocketFactory, Serializable |
分别在服务端指定安全证书库:
服务端:
-Djavax.net.ssl.keyStore=F:/keystore.jks
-Djavax.net.ssl.keyStorePassword=changeit
客户端:
-Djavax.net.ssl.trustStore=F:/cacerts.jks
-Djavax.net.ssl.trustStorePassword=changeit
通信正常。原理不复杂,类似文章也比较多,就不写了。贴几个大家自个看吧:
https://blogs.oracle.com/lmalventosa/entry/using_the_ssl_tls_based
http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/socketfactory/SSLInfo.html