2009-11-04 3 views
3

Я использую JConsole для доступа к моим приложениям MBeans и использую файл password.properties. Но по спецификации Sun этот файл содержит только пароли только в текстовых форматах.Как шифровать пароли для файла паролей JConsole

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

Теперь я хотел бы, чтобы зашифровать пароль и использовать его для аутентификации пользователя JMX из JConsole (имени пользователя и пароля в разделе Remote). Я мог бы использовать любую предопределенную логику шифрования или собственные алгоритмы шифрования.

Кто-нибудь знает о таком перехвате, чтобы сменить пароль обычного текста на зашифрованный, чтобы JMX Framework тоже знал о зашифрованном пароле?

Мой текущий пароль файла:

guest guest 
admin admin 

С шифрованием он должен выглядеть следующим образом:

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

Здравствуйте EclipseGuru, вы можете предоставить любые обновления по этому вопросу? Я столкнулся с аналогичной проблемой, как вы настроили зашифрованные пароли в файле «jmxremote.password»? Пожалуйста помоги. –

ответ

7

Вы можете использовать параметр конфигурации 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

+0

Большое спасибо за быстрый пост. Сегодня я попробую этот материал и дам вам знать. Но в целом это то, что я ищу. – EclipseGuru

+0

Карта 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