2009-04-28 29 views
71

¿Cómo puedo obtener el nombre de usuario/nombre de usuario en Java?Obtener nombre de usuario de inicio de sesión en java

Este es el código que he intentado ...

try{ 
    LoginContext lc = new LoginContext(appName,new TextCallbackHandler()); 
    lc.login(); 
    Subject subject = lc.getSubject(); 
    Principal principals[] = (Principal[])subject.getPrincipals().toArray(new Principal[0]); 

    for (int i=0; i<principals.length; i++) { 
     if (principals[i] instanceof NTUserPrincipal || principals[i] instanceof UnixPrincipal) { 
      String loggedInUserName = principals[i].getName(); 
     } 
    } 

} 
catch(SecurityException se){ 
    System.out.println("SecurityException: " + se.getMessage()); 
} 

me siento un SecurityException cuando trato de ejecutar este código. ¿Podría alguien decirme por favor si voy en la dirección correcta y ayudarme a comprender el problema?

+2

me temo no entender, pero no entiendo su pregunta. ¿Qué usuario de inicio de sesión? ¿Inicio de sesión de Windows/GNU Linux? Autenticación básica en un servidor web? – guerda

+0

Es imposible entender nada cuando no se publican detalles –

+0

Lo siento muchachos. Soy nuevo en Java y ahora es un poco difícil tener sentido. –

Respuesta

175
System.getProperty("user.name") 
+3

+1 puede imprimir System.properties para obtener mucha información, la VM se inicializa con –

+0

¡Gracias!Vengo de Flash/actionscript ... así que tengo un montón de cosas para cubrir :) –

+1

Para mí, esto imprime el nombre del usuario que ejecuta la máquina virtual. No es el usuario registrado en la aplicación Java. –

27

en Unix:

new com.sun.security.auth.module.UnixSystem().getUsername() 

en Windows:

new com.sun.security.auth.module.NTSystem().getName() 

en Solaris:

new com.sun.security.auth.module.SolarisSystem().getUsername() 
+37

Este código va en contra de la filosofía de Java de escribir una vez, ejecutar en cualquier lugar (introducción de código específico del sistema operativo), y en segundo lugar, crea una dependencia en la implementación de Sun de Java. –

+12

Intentar obtener el nombre de usuario es, por definición, específico de la plataforma. Una JVM que se ejecuta en un sistema de usuario único puede no tener un nombre de usuario en absoluto. –

+6

@ChinmayKanchi: Si no hay un nombre de usuario, entonces la propiedad 'user.name' debería ser nula. Estoy de acuerdo con @JinKim, no escribas cosas dependientes del sistema operativo. –

14

System.getProperty ("user.name") no es una buena opción de seguridad ya que esa variable de entorno podría ser fingida: C: \ Ajuste NOMBRE DE USUARIO = "Joe Doe" java ... // le dará System.getProperty ("user.name") que debe hacer:

com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem(); 
System.out.println(NTSystem.getName()); 

JDK 1.5 y mayor.

Lo uso dentro de un applet, y tiene que estar firmado. info source

+0

Muy útil +1! ¡Gracias! –

+2

Esta no es una solución completa, ya que solo funciona en Windows. –

+1

¿Podría esto ser falso también, p. con un cargador de clases personalizado o una implementación personalizada de 'com.sun.security.auth.module.NYSystem' superior en classpath? No sé si el tiempo de ejecución de Java trata de evitar tales exploits, pero no creo que haya una forma impracticable de hacerlo 'seguro', excepto al ejecutar el código en un recuadro que es inaccesible para el cliente potencialmente malintencionado. . – bacar

13

inspirado por @newacct 's respuesta, un código que puede ser compilado en cualquier plataforma:

String osName = System.getProperty("os.name").toLowerCase(); 
String className = null; 
String methodName = "getUsername"; 

if(osName.contains("windows")){ 
    className = "com.sun.security.auth.module.NTSystem"; 
    methodName = "getName"; 
} 
else if(osName.contains("linux")){ 
    className = "com.sun.security.auth.module.UnixSystem"; 
} 
else if(osName.contains("solaris") || osName.contains("sunos")){ 
    className = "com.sun.security.auth.module.SolarisSystem"; 
} 

if(className != null){ 
    Class<?> c = Class.forName(className); 
    Method method = c.getDeclaredMethod(methodName); 
    Object o = c.newInstance(); 
    System.out.println(method.invoke(o)); 
} 
+0

Buen uso de la reflexión :) – Zizouz212

+3

Esto se romperá en Windows ya que el método en NTSystem para obtener el nombre de usuario es "getName()" y no "getUsername()". Supongo que puedes hacer una nueva verificación y luego invocar el método correcto. Bizarre esto no es abstraído en un mecanismo agnóstico del sistema operativo por el JRE sin embargo? –

2

El 'set nombre de usuario = "nombre de usuario"' es una anulación temporal que sólo existe mientras las ventanas de cmd estén todavía arriba, una vez que se elimina, la variable pierde valor. Así que creo que el

System.getProperty ("user.name");

es un código corto y preciso de usar.

1

System.getenv().get("USERNAME"); - works on windows!

¡En las propiedades del entorno tiene la información que necesita sobre la computadora y el host! ¡Estoy diciendo otra vez! Funciona en WINDOWS!

+0

¿Qué pasa con 'System.getenv (" nombre de usuario ")'? :) –

5

Usando JNA su simple:

String username = Advapi32Util.getUserName(); 
System.out.println(username); 

Advapi32Util.Account account = Advapi32Util.getAccountByName(username); 
System.out.println(account.accountType); 
System.out.println(account.domain); 
System.out.println(account.fqn); 
System.out.println(account.name); 
System.out.println(account.sidString); 

https://github.com/java-native-access/jna

+0

Esto no funciona si ha iniciado sesión como usuario de dominio pero también hay un usuario local del mismo nombre. getAccountByName devolverá información para el usuario local. – Dave

Cuestiones relacionadas