我花了很多精力将支持JMX添加到企业应用程序中。 JMX应该使用SQL的SSL和客户端身份验证。这不是问题。 我正在使用系统属性来启用SSL。 系统属性是JVM的全局属性。特别是在大型应用程序中,如果没有其他配置方法,冲突很快就会出现。
特别是在大型企业应用程序中,需要对需要不同证书的不同服务进行调用,特别是对于自动证书选择的限制,需要有一种方法可以在需要时通过灵活的代码挂钩。 不幸的是,JMX和RMI目前没有提供这样的钩子,完全依赖于系统属性或默认套接字工厂。
有没有办法让JMX使用SSL而不使用系统属性?
编辑:
使用SslRMIClientSocketFactory不起作用。
// System.setProperty( "java.rmi.server.randomIDs", "true" );
// System.setProperty( "javax.net.ssl.keyStore", keystore );
// System.setProperty( "javax.net.ssl.keyStorePassword",
// "password" );
// SSL-based RMI socket factories.
SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
map.put( RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf );
map.put( RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf );
例外:
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:304)
答案 0 :(得分:0)
您可以创建自己的RMIConnectorServer,并有条件地为SSL启用它。构建服务器实例时,可以使用已定义的RMIClientSocketFactory和RMIServerSocketFactory实例加载环境映射。要启用SSL,可以将这些工厂设置为已配置的SslRMIClientSocketFactory和SslRMIServerSocketFactory实例,并且您将重新创建系统道具配置的连接器服务器的等效项。我没有用SSL做过这件事,但似乎记录得很清楚。
答案 1 :(得分:0)
解决方案:
SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
SslRMIServerSocketFactory ssf = createSslRMIServerSocketFactory(null,null,false);
map.put( RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf );
map.put( RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf );
....
private static SslRMIServerSocketFactory createSslRMIServerSocketFactory(
String[] enabledCipherSuites, String[] enabledProtocols,
boolean sslNeedClientAuth )
{
try
{
// Load the SSL keystore properties from the config file
String keyStore = "KeyStore.jks";
String keyStorePassword = "pass";
String trustStore = "truststore";
String trustStorePassword = "pass";
char[] keyStorePasswd = null;
if ( keyStorePassword.length() != 0 )
{
keyStorePasswd = keyStorePassword.toCharArray();
}
char[] trustStorePasswd = null;
if ( trustStorePassword.length() != 0 )
{
trustStorePasswd = trustStorePassword.toCharArray();
}
KeyStore ks = null;
if ( keyStore != null )
{
ks = KeyStore.getInstance( KeyStore.getDefaultType() );
FileInputStream ksfis = new FileInputStream( keyStore );
try
{
ks.load( ksfis, keyStorePasswd );
}
finally
{
ksfis.close();
}
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance( KeyManagerFactory
.getDefaultAlgorithm() );
kmf.init( ks, keyStorePasswd );
KeyStore ts = null;
if ( trustStore != null )
{
ts = KeyStore.getInstance( KeyStore.getDefaultType() );
FileInputStream tsfis = new FileInputStream( trustStore );
try
{
ts.load( tsfis, trustStorePasswd );
}
finally
{
tsfis.close();
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory
.getDefaultAlgorithm() );
tmf.init( (KeyStore) ts );
SSLContext ctx = SSLContext.getInstance( "SSL" );
ctx.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
return new SslRMIServerSocketFactory ( ctx, enabledCipherSuites, enabledProtocols,
sslNeedClientAuth );
}
catch ( Exception e )
{
Logger.getGlobal().log( Level.SEVERE, e.getMessage() );
return null;
}
}