获取java中的登录用户名

Geo*_*nza 83 java username

如何在Java中获取用户名/登录名?

这是我试过的代码......

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());
}
Run Code Online (Sandbox Code Playgroud)

SecurityException当我尝试运行此代码时,我得到了一个.有人可以告诉我,我是否正朝着正确的方向前进,并帮助我理解这个问题.

dfa*_*dfa 204

System.getProperty("user.name")
Run Code Online (Sandbox Code Playgroud)

  • +1您可以打印System.properties以获取VM初始化的大量信息 (4认同)
  • 对我来说,这会打印执行VM的用户的名称.不是java应用程序上的登录用户. (3认同)

new*_*cct 29

在Unix中:

new com.sun.security.auth.module.UnixSystem().getUsername()
Run Code Online (Sandbox Code Playgroud)

在Windows中:

new com.sun.security.auth.module.NTSystem().getName()
Run Code Online (Sandbox Code Playgroud)

在Solaris中:

new com.sun.security.auth.module.SolarisSystem().getUsername()
Run Code Online (Sandbox Code Playgroud)

  • 这段代码违反了Java的一次编写理念,在任何地方运行(引入特定于操作系统的代码),其次,它创建了对Sun的Java实现的依赖. (49认同)
  • 根据定义,尝试获取用户名是特定于平台的.在单用户系统上运行的JVM可能根本没有用户名. (14认同)
  • @ChinmayKanchi:如果没有用户名,那么`user.name`属性应该为null.我同意@JinKim,不要编写依赖于操作系统的东西. (8认同)
  • 开发人员不应使用com.sun包下的类.它们是内部的,将来可能会发生变化. (3认同)
  • user.name可以在命令行上设置,因此它在很大程度上取决于用例 (2认同)

cel*_*owm 16

@newacct的回答启发,可以在任何平台上编译的代码:

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 ) );
}
Run Code Online (Sandbox Code Playgroud)

  • 这将在Windows上中断,因为在NTSystem上获取用户名的方法是"getName()"而不是"getUsername()".我想你可以做进一步检查,然后调用正确的方法.奇怪的是,这不是由JRE抽象为OS不可知机制的吗? (5认同)

pdj*_*ota 15

System.getProperty("user.name")不是一个好的安全选项,因为该环境变量可能是伪造的:C:\ set USERNAME ="Joe Doe"java ... //将为您提供System.getProperty("user.名称")你应该这样做:

com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem();
System.out.println(NTSystem.getName());
Run Code Online (Sandbox Code Playgroud)

JDK 1.5及更高版本.

我在applet中使用它,它必须签名. 信息来源

  • 这不是一个完整的解决方案,因为它只能在Windows下运行. (4认同)
  • 我只是成功设法使用PowerMock替换NTSystem.getName()的实现(我相信使用自定义类加载器),所以你真的不能依赖这样的东西来'安全'......但是我不知道小程序世界中的事情如何.我原以为如果有人可以提供自定义系统属性,那么他们也可以提供自定义类或自定义类加载器. (4认同)

ANT*_*ARA 6

使用JNA简单:

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);
Run Code Online (Sandbox Code Playgroud)

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