2009-11-04 82 views
3

我正在使用JConsole访问我的应用程序MBean,并使用password.properties文件。但根据Sun的规范,此文件仅包含明文格式的密码。如何加密JConsole密码文件的密码

com.sun.management.jmxremote.password.file=<someLocation>/password.properties

现在我想对密码进行加密,并使用它从JConsole的(在远程段的用户名和密码字段)的JMX用户认证。我可以使用任何预定义的加密逻辑或我自己的加密算法。

有谁知道任何这样的截取将纯文本密码更改为加密密码,以便JMX框架也知道加密密码?

我目前的密码文件:

guest guest 
admin admin 

加密就应该是这样的:

guest ENC(RjqpRYbAOwbAfAEDBdHJ7Q4l/GO5IoJidZctNT5oG64=) 
admin ENC(psg3EnDei6fVRuqHeLwOqNTgIWkwQTjI2+u2O7MXXWc=) 
+0

你好EclipseGuru,可以为您提供这方面的任何更新?我遇到了类似的问题,您是如何在“jmxremote.password”文件中配置加密密码的?请帮忙。 – 2015-02-13 05:41:43

回答

7

可以在management.properties文件中使用的配置参数com.sun.management.jmxremote.login.config(参见%JAVA_HOME%/ lib目录/management/management.properties)来配置要使用的Authenticator和LoginModule。

默认如下:

JMXPluggableAuthenticator { 
    com.sun.jmx.remote.security.FileLoginModule required; 
}; 

读取明文密码文件jmxremote.password。由于com.sun.jmx.remote.security.JMXPluggableAuthenticator可以重新配置为 以使用任何LoginModule实现,您可以自由选择现有的LoginModule或实现您自己的使用加密密码文件的 。

要重新实现FileLoginModule,你应该看看attemptAuthentication(boolean)方法,其中 实际上执行身份验证,你可能会取代。实现javax.security.auth.spi.LoginModule接口 并使用给定的CallbackHandler(您将从init()方法获得它)来请求用户名和密码。加密/散列收到的密码,并将其与加密的密码文件中读取的密码进行比较。伪代码:

public class EncryptedFileLoginModule implements LoginModule { 

@Override 
public void initialize(Subject subject, CallbackHandler callbackHandler, 
     Map<String, ?> sharedState, Map<String, ?> options) { 
    this.subject = subject; 
    this.callbackHandler = callbackHandler; 
} 

public boolean login() throws LoginException { 
    attemptLogin(); 
    if (username == null || password == null) { 
     throw new LoginException("Either no username or no password specified"); 
    } 
    MessageDigest instance = MessageDigest.getInstance("SHA-1"); 
    byte[] raw = new String(password).getBytes(); 
    byte[] crypted = instance.digest(raw); 
    // TODO: Compare to the one stored locally 
    if (!authenticated) throw new LoginException(); 
    return true; 
} 

private void attemptLogin() throws LoginException { 
    Callback[] callbacks = new Callback[2]; 
    callbacks[0] = new NameCallback("username"); 
    callbacks[1] = new PasswordCallback("password", false); 
     callbackHandler.handle(callbacks); 
     username = ((NameCallback) callbacks[0]).getName(); 
     user = new JMXPrincipal(username); 
     char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword(); 
     password = new char[tmpPassword.length]; 
     System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length); 
     ((PasswordCallback) callbacks[1]).clearPassword(); 
} 

然而,由于这已经是服务器端,密码会被AFAIK仍然采用明文形式传输,如果你不执行 JMX通过SSL。因此,要么强制使用SSL,要么使用另一种传输协议机制,在传输它们之前对凭证进​​行编码。

总之,依靠JAAS提供的现有认证机制可能要好得多。例如,如果您在本地Windows环境中运行 ,则可以轻松使用NTLoginModule进行自动登录。但它只适用于本地机器。

创建一个文件c:/temp/mysecurity.cfg:

MyLoginModule { 
com.sun.security.auth.module.NTLoginModule REQUIRED debug=true debugNative=true; 
}; 

接下来,配置jmxremote。访问文件包含您希望授予您的JMX访问服务器的用户名或角色:

monitorRole readonly 
controlRole readwrite ... 
mhaller readonly 

(我建议启用调试模式,直到它的作品你会看到所有的用户名,域名和组名称时用户试图登录) 设置以下JVM参数为您的服务器:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=8686 
-Dcom.sun.management.jmxremote.authenticate=true 
-Dcom.sun.management.jmxremote.ssl=true 
-Djava.net.preferIPv4Stack=true 
-Djava.security.auth.login.config=c:/temp/mysecurity.cfg 
-Dcom.sun.management.jmxremote.login.config=MyLoginModule 

启动应用程序,并尝试使用的JConsole或VisualVM的连接。

请注意,JConsole,您将需要指定用户名和密码,虽然它不会被使用。任何密码和任何用户名都可以使用。 原因是因为jconsole将尝试使用空的用户名和空密码进行身份验证,该密码显式阻止。 当用户未输入任何内容时,VisualVM通过为用户名和密码使用空字符串做得更好。

还要注意的是远程连接的时候,我想你将不得不使用更复杂的登录模块, 但是Sun已经为他们提供足够的NTLoginModule不起作用:

  • com.sun.security .auth.module.Krb5LoginModule:进行身份验证使用Kerberos协议
  • com.sun.security.auth.module.LdapLoginModule用户:(新Java 6中):通过指定技术连接用户
  • 执行针对LDAP服务器认证
  • com.sun.security.auth.module.JndiLoginModule:执行身份验证针对在JNDI上下文中注册的LDAP服务器
  • com.sun.security.auth.module.KeyStoreLoginModule:使用Java的用户进行身份验证密钥库。支持PIN或智能卡身份验证。

你会希望有一个看看LdapLoginModule

+0

非常感谢快速发布。我今天会尝试这个东西,让你知道。但总的来说,这是我正在寻找的。 – EclipseGuru 2009-11-04 23:37:50

+0

Map env = new HashMap (); env.put(ApplicationProperties.JMX_PWD_FILE_PROP,pwdFile); env.put(ApplicationProperties.JMX_ACCESS_FILE_PROP,accFile); env.put(“com.sun.management.jmxremote.login.config”,“ABCDJMXLoginModule”); connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL,env,mBeanServer); 是否可以按照上述方式使用新的LoginProfile类。我正在尝试使用ABCDJMXLoginModule进行身份验证,但由于某种原因无法正常工作。任何线索? – EclipseGuru 2010-01-26 19:47:16