可以在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