How can I get the username/login name in Java?
This is the code I have tried...
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()); } I get a SecurityException when I try to run this code. Could someone please tell me whether I'm heading in the right direction, and help me to understand the problem.
9 Answers
System.getProperty("user.name"); 4in Unix:
new com.sun.security.auth.module.UnixSystem().getUsername() in Windows:
new com.sun.security.auth.module.NTSystem().getName() in Solaris:
new com.sun.security.auth.module.SolarisSystem().getUsername() 7inspired by @newacct's answer, a code that can be compiled in any platform:
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 ) ); } 5System.getProperty("user.name") is not a good security option since that environment variable could be faked: C:\ set USERNAME="Joe Doe" java ... // will give you System.getProperty("user.name") You ought to do:
com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem(); System.out.println(NTSystem.getName()); JDK 1.5 and greater.
I use it within an applet, and it has to be signed. info source
6Using JNA its 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); 1The 'set Username="Username" ' is a temporary override that only exists as long as the cmd windows is still up, once it is killed off, the variable loses value. So i think the
System.getProperty("user.name");
is still a short and precise code to use.
System.getenv().get("USERNAME"); - works on windows !
In environment properties you have the information you need about computer and host! I am saying again! Works on WINDOWS !
2Below is a solution for WINDOWS ONLY
In cases where the application (like Tomcat) is started as a windows service, the System.getProperty("user.name") or System.getenv().get("USERNAME") return the user who started the service and not the current logged in user name.
Also in Java 9 the NTSystem etc classes will not be accessible
So workaround for windows: You can use wmic, so you have to run the below command
wmic ComputerSystem get UserName If available, this will return output of the form:
UserName {domain}\{logged-in-user-name} Note: For windows you need to use cmd /c as a prefix, so below is a crude program as an example:
Process exec = Runtime.getRuntime().exec("cmd /c wmic ComputerSystem get UserName".split(" ")); System.out.println(exec.waitFor()); try (BufferedReader bw = new BufferedReader(new InputStreamReader(exec.getInputStream()))) { System.out.println(bw.readLine() + "\n" + bw.readLine()+ "\n" + bw.readLine()); } 1I tested in linux centos
Map<String, String> env = System.getenv(); for (String envName : env.keySet()) { System.out.format("%s=%s%n", envName, env.get(envName)); } System.out.println(env.get("USERNAME"));