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
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. –