web-dev-qa-db-fra.com

Masquer l'entrée en ligne de commande

Je sais que les interfaces de ligne de commande telles que Git et d'autres peuvent masquer les entrées d'un utilisateur (utile pour les mots de passe). Existe-t-il un moyen de le faire par programmation en Java? Je suis en train de saisir le mot de passe d'un utilisateur et j'aimerais que son entrée soit "masquée" sur cette ligne particulière (mais pas sur toutes les personnes). Voici mon code pour cela (bien que je doute que cela soit utile ...)

try (Scanner input = new Scanner(System.in)) {
  //I'm guessing it'd probably be some property you set on the scanner or System.in right here...
  System.out.print("Please input the password for " + name + ": ");
  password = input.nextLine();
}
57
kentcdodds

Essayez Java.io.Console.readPassword . Vous devrez exécuter au moins Java 6 cependant.

   /**
    * Reads a password or passphrase from the console with echoing disabled
    *
    * @throws IOError
    *         If an I/O error occurs.
    *
    * @return  A character array containing the password or passphrase read
    *          from the console, not including any line-termination characters,
    *          or <tt>null</tt> if an end of stream has been reached.
    */
    public char[] readPassword() {
        return readPassword("");
    }

Attention cependant, ceci ne fonctionne pas avec la console Eclipse. Vous devrez exécuter le programme à partir d'une console/shell true pour pouvoir le tester.

85
adarshr

Oui peut être fait. Ceci s'appelle le masquage d'entrée de ligne de commande. Vous pouvez implémenter cela facilement.

Vous pouvez utiliser un thread séparé pour effacer les caractères renvoyés lors de la saisie et les remplacer par des astérisques. Ceci est fait en utilisant la classe EraserThread ci-dessous

import Java.io.*;

class EraserThread implements Runnable {
   private boolean stop;

   /**
    *@param The Prompt displayed to the user
    */
   public EraserThread(String Prompt) {
       System.out.print(Prompt);
   }

   /**
    * Begin masking...display asterisks (*)
    */
   public void run () {
      stop = true;
      while (stop) {
         System.out.print("\010*");
     try {
        Thread.currentThread().sleep(1);
         } catch(InterruptedException ie) {
            ie.printStackTrace();
         }
      }
   }

   /**
    * Instruct the thread to stop masking
    */
   public void stopMasking() {
      this.stop = false;
   }
}

En utilisant ce fil

public class PasswordField {

   /**
    *@param Prompt The Prompt to display to the user
    *@return The password as entered by the user
    */
   public static String readPassword (String Prompt) {
      EraserThread et = new EraserThread(Prompt);
      Thread mask = new Thread(et);
      mask.start();

      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      String password = "";

      try {
         password = in.readLine();
      } catch (IOException ioe) {
        ioe.printStackTrace();
      }
      // stop masking
      et.stopMasking();
      // return the password entered by the user
      return password;
   }
}

Ce lien discuter en détail.

13

JLine 2 peut être d’intérêt. En plus du masquage de caractères, il fournit des fonctions d’achèvement, d’édition et d’historique en ligne de commande. Par conséquent, il est très utile pour un outil Java) basé sur la CLI.

Pour masquer votre saisie:

String password = new jline.ConsoleReader().readLine(new Character('*'));
8
Brian Agnew

Il y a :

Console cons;
char[] passwd;
if ((cons = System.console()) != null &&
    (passwd = cons.readPassword("[%s]", "Password:")) != null) {
    ...
    Java.util.Arrays.fill(passwd, ' ');
}

source

mais je ne pense pas que cela fonctionne avec un IDE comme Eclipse car le programme est exécuté en tant que processus en arrière-plan plutôt qu'en tant que processus de niveau supérieur avec une fenêtre de console.

Une autre approche consiste à utiliser le JPasswordField in swing avec la méthode associée actionPerformed:

public void actionPerformed(ActionEvent e) {
    ...
    char [] p = pwdField.getPassword();
}

source

3
Dhruv Gairola

La classe Console a une méthode readPassword() qui pourrait résoudre votre problème.

0
rlinden