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