Вы можете использовать параметр конфигурации com.sun.management.jmxremote.login.config
в файле management.properties (см% 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
(рекомендую включить режим отладки, пока он работает вы увидите все имена пользователей, доменные имена и имена групп, когда пользователь пытается войти) Установить следующие аргументы виртуальной машины Java для вашего сервера:
-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 выполняет лучшую работу, используя пустые строки для имени пользователя и пароля, когда пользователь не вводит ни одного пользователя.
Также отметим, что NTLoginModule не работает при удаленном подключении, я думаю, что вы должны использовать более сложный модуль входа в систему, но ВС уже обеспечивает их достаточно:
- com.sun.security .auth.module.Krb5LoginModule: Идентифицирует пользователь с помощью протоколов Kerberos
- com.sun.security.auth.module.LdapLoginModule: (новый в Java 6): Выполняет проверку подлинности от сервера LDAP, указав технический пользователя соединения
- com.sun.security.auth.module.JndiLoginModule: выполняет аутентификацию на сервере LDAP, зарегистрированного в контексте JNDI
- com.sun.security.auth.module.KeyStoreLoginModule: Идентифицирует пользователей с помощью Java Keystore. Поддерживает аутентификацию PIN-кода или смарт-карты.
Вы хотите, чтобы взглянуть на LdapLoginModule
Здравствуйте EclipseGuru, вы можете предоставить любые обновления по этому вопросу? Я столкнулся с аналогичной проблемой, как вы настроили зашифрованные пароли в файле «jmxremote.password»? Пожалуйста помоги. –