2009-11-04 39 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