获取java中的登录用户名

获取java中的登录用户名,java,authentication,Java,Authentication,如何在Java中获取用户名/登录名 这是我尝试过的代码 try{ LoginContext lc = new LoginContext(appName,new TextCallbackHandler()); lc.login(); Subject subject = lc.getSubject(); Principal principals[] = (Principal[])subject.getPrincipals().toArray(new Principal

如何在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());
}
试试看{
LoginContext lc=新的LoginContext(appName,new TextCallbackHandler());
lc.login();
Subject-Subject=lc.getSubject();
主体主体[]=(主体[])subject.getPrincipals().toArray(新主体[0]);
对于Unix中的(int i=0;i)

new com.sun.security.auth.module.UnixSystem().getUsername()
在Windows中:

new com.sun.security.auth.module.NTSystem().getName()
在Solaris中:

new com.sun.security.auth.module.SolarisSystem().getUsername()
System.getProperty(“user.name”)不是一个好的安全选项,因为该环境变量可能是伪造的: C:\set USERNAME=“乔·多伊” JAVA //将为您提供System.getProperty(“user.name”) 你应该做:

com.sun.security.auth.module.NTSystem NTSystem = new com.sun.security.auth.module.NTSystem();
System.out.println(NTSystem.getName());
JDK1.5及更高版本

我在applet中使用它,并且必须对它进行签名。
灵感来自@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 ) );
}
String osName=System.getProperty(“os.name”).toLowerCase();
字符串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){
类别c=类别forName(类别名称);
方法Method=c.getDeclaredMethod(方法名);
对象o=c.newInstance();
System.out.println(方法调用(o));
}
set Username=“Username”是一个临时覆盖,它只在cmd窗口打开时才存在,一旦关闭,变量就会失去值。因此我认为

System.getProperty(“user.name”)

仍然是一个简短而精确的代码。

System.getenv().get(“用户名”);
-在windows上工作

在environment properties中,您可以获得有关计算机和主机的信息!我再说一遍!在WINDOWS上工作!

使用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);

以下是仅适用于WINDOWS的解决方案

在应用程序(如Tomcat)作为windows服务启动的情况下,System.getProperty(“user.name”)或System.getenv().get(“用户名”)返回启动服务的用户,而不是当前登录的用户名

同样在Java 9中,NTSystem etc类也不可访问

windows的解决方法:您可以使用wmic,因此必须运行以下命令

wmic ComputerSystem get UserName
如果可用,这将返回表单的输出:

UserName
{domain}\{logged-in-user-name}
注意:对于windows,您需要使用cmd/c作为前缀,因此下面是一个粗略的程序示例:

    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());
    }

我在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")); 
Map env=System.getenv();
对于(字符串envName:env.keySet()){
System.out.format(“%s=%s%n”,envName,env.get(envName));
}
System.out.println(env.get(“用户名”);


+1您可以打印System.properties来获取大量信息,VM是用它初始化的。对于我来说,这打印的是执行VM的用户的名称,而不是java应用程序上登录的用户。这是在广泛可用的第三方库中定义的吗?还是在JDK提供的类中为
user.name
property name?我恐怕会误解你,但我不理解你的问题。哪个登录用户名?Windows/GNU Linux登录?Web服务器上的基本身份验证?如果不发布详细信息,就不可能理解任何内容。该代码违背了Java的“一次编写,随时随地运行”的理念(操作系统特定代码介绍),其次,它创建了对Sun的Java实现的依赖。根据定义,获取用户名是特定于平台的。在单用户系统上运行的JVM可能根本没有用户名。@ChinmayKanchi:如果没有用户名,则
user.name
属性应该为空。我同意@JinKim,不要编写OS dependent stuff.user.name可以在命令行上设置,因此这在很大程度上取决于com.sun包下的类的用例是什么,开发人员不应该使用。它们是内部的,将来可能会更改。这不是一个完整的解决方案,因为它只在Windows下工作。这是否也会被欺骗,例如使用自定义类加载器或自定义类加载器实现类路径中更高级别的
com.sun.security.auth.module.NYSystem
?我不知道Java运行时是否试图防止此类攻击,但我认为除了在潜在恶意客户端无法访问的框上运行代码之外,不会有任何不可靠的方法使其“安全”。我刚刚成功地naged使用PowerMock替换NTSystem.getName()的实现(我相信它使用自定义类加载器),所以你真的不能依靠这样的东西来实现“安全性”…但是我不知道小程序世界里的情况如何。我本以为如果有人可以提供自定义系统属性,那么他们也可以提供自定义类或自定义类加载器。-1因为它只在Windows上工作。你不应该使用它。@bacar:我同意,那是在Windows上e不应该依赖于这一点,认为一个人是相当安全的。但在我看来,安全是关于“级别”的。而且更改环境变量比使用PowerMock方法更容易。在一家使用NTSystem而不是环境变量的非it公司中,能够实现此功能的人数比能够实现此功能的人数多一半:P。因此,您获得了更高的安全性,但反过来又失去了一些java约定。反射的良好使用:)这将在Windows上中断,因为NTSystem上获取用户名的方法是“getName()”而不是“getUsername()”。我想你可以做进一步的检查,然后调用正确的方法。奇怪的是,JRE并没有将其抽象为操作系统不可知的机制?Java 9+默认情况下无法访问
com.sun
类。此解决方案不适用于它。除非添加一些新的API,否则我认为在Java 9中唯一有效的方法是.那
系统呢
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"));