2009-11-04 12 views
3

J'utilise le JConsole pour accéder à mon application MBeans et j'utilise le fichier password.properties. Mais selon les spécifications du Sun, ce fichier contient uniquement des mots de passe en format texte clair.Comment crypter les mots de passe pour le fichier de mot de passe JConsole

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

Maintenant, je veux chiffrer le mot de passe et de l'utiliser pour l'authentification utilisateur JMX de JConsole (les champs nom d'utilisateur et mot de passe dans la section à distance). Je pourrais utiliser n'importe quelle logique de chiffrement prédéfinie ou mes propres algorithmes de chiffrement.

Est-ce que quelqu'un est au courant d'une telle interception pour changer le mot de passe en texte brut en mot de passe crypté afin que JMX Framework connaisse aussi le mot de passe crypté?

Mon fichier de mot de passe actuel:

guest guest 
admin admin 

Avec cryptage, il devrait ressembler à:

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

Bonjour EclipseGuru, pouvez-vous fournir une mise à jour à ce sujet? Je suis confronté à un problème similaire, comment avez-vous configuré les mots de passe cryptés dans le fichier "jmxremote.password"? S'il vous plaît aider. –

Répondre

7

Vous pouvez utiliser le paramètre de configuration com.sun.management.jmxremote.login.config dans le fichier management.properties (voir% JAVA_HOME%/lib /management/management.properties) pour configurer l'Authenticator et le LoginModule à utiliser.

La valeur par défaut est le suivant:

JMXPluggableAuthenticator { 
    com.sun.jmx.remote.security.FileLoginModule required; 
}; 

qui lit le fichier de mot de passe de texte brut jmxremote.password. Puisque le com.sun.jmx.remote.security.JMXPluggableAuthenticator peut être reconfiguré pour utiliser une implémentation de LoginModule, vous êtes libre de choisir un LoginModule existant ou d'implémenter votre propre qui utilise des fichiers de mots de passe cryptés. Pour réimplémenter FileLoginModule, vous devriez jeter un oeil à la méthode attemptAuthentication(boolean), qui effectue réellement l'authentification et que vous allez probablement remplacer. Implémentez l'interface javax.security.auth.spi.LoginModule et utilisez le CallbackHandler donné (vous l'obtiendrez de la méthode init()) pour demander un nom d'utilisateur et un mot de passe. Chiffrer/hacher le mot de passe reçu et le comparer à celui lu dans votre fichier de mot de passe crypté. Code Pseudo:

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(); 
} 

Cependant, comme cela est déjà le côté serveur, le mot de passe serait encore être transféré afaik en clair si vous ne l'applique pas JMX sur SSL. Ainsi, soit appliquer SSL ou utiliser un autre mécanisme de protocole de transport qui code les informations d'identification avant les transmettre sur le fil. En conclusion, il est peut-être préférable de s'appuyer sur les mécanismes d'authentification existants fournis par JAAS. Si, par exemple, vous exécutez dans un environnement Windows local, vous pouvez facilement utiliser le NTLoginModule pour la connexion automatique. Mais cela ne fonctionne que sur la machine locale.

Créer un fichier c: /temp/mysecurity.cfg:

MyLoginModule { 
com.sun.security.auth.module.NTLoginModule REQUIRED debug=true debugNative=true; 
}; 

Ensuite, configurer le jmxremote.fichier d'accès pour contenir les noms d'utilisateur ou les rôles que vous souhaitez autoriser l'accès à votre serveur JMX.

monitorRole readonly 
controlRole readwrite ... 
mhaller readonly 

(je vous recommande d'activer le mode de débogage jusqu'à ce qu'il fonctionne Vous verrez tous les noms d'utilisateur, les noms de domaine et les noms de groupe lorsque un utilisateur tente de se connecter) Définissez les arguments JVM suivants pour votre serveur:

-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 

Démarrez votre application et essayez de vous connecter en utilisant JConsole ou VisualVM. Notez que JConsole, vous devrez spécifier un nom d'utilisateur et un mot de passe, même si cela ne va pas être utilisé. Tout mot de passe et tout nom d'utilisateur fonctionneront. La raison est que jconsole essaie de s'authentifier avec un nom d'utilisateur nul et un mot de passe nul, qui est explicitement bloqué. VisualVM fait un meilleur travail en utilisant des chaînes vides pour le nom d'utilisateur et le mot de passe quand aucun n'est entré par l'utilisateur.

Notez également que le NTLoginModule ne fonctionne pas lors de la connexion à distance, je pense que vous devez utiliser un module de connexion plus sophistiqué, mais Sun fournit déjà assez d'entre eux:

  • com.sun.security .auth.module.Krb5LoginModule: authentifie les utilisateurs en utilisant les protocoles Kerberos
  • com.sun.security.auth.module.LdapLoginModule: (nouveau en Java 6): l'authentification contre un Réalise serveur LDAP en spécifiant la connexion technique utilisateur
  • com.sun.security.auth.module.JndiLoginModule: l'authentification contre un Réalise serveur LDAP enregistré dans le contexte JNDI
  • com.sun.security.auth.module.KeyStoreLoginModule: authentifie les utilisateurs en utilisant Java Keystore. Prend en charge l'authentification par code PIN ou par carte à puce.

Vous voulez jeter un oeil à la LdapLoginModule

+0

Merci beaucoup pour le message rapide. Je vais essayer ce truc aujourd'hui et vous le faire savoir. Mais en général c'est ce que je cherche. – EclipseGuru

+0

Mappe 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); Est-il possible d'utiliser la nouvelle classe LoginProfile de la manière ci-dessus. J'essaye d'employer ABCDJMXLoginModule pour l'authentification mais ne fonctionne pas pour une raison quelconque. Des indices? – EclipseGuru