【问题标题】:How to get the remote user's username in java如何在java中获取远程用户的用户名
【发布时间】:2014-07-30 08:09:20
【问题描述】:

我正在开发没有任何登录机制的应用程序,我组织中的任何用户都可以使用它。但我想选择将使用我的工具的远程用户的用户名。我有一个点击按钮,我想获取他们的用户名。

我试过request.getRemoteUser 得到null。尝试System.getenv("USERNAME") 获取服务器所在本地主机的登录用户。试过getHostNameSystem.getProperty 得到了本地主机名。也试过这个 - new com.sun.security.auth.module.NTSystem().getName() 但结果相同。

我正在使用 java6、windows 服务器和 glassfish3 服务器。

请提出一些建议,因为我不想使用任何外部链接和工具。

【问题讨论】:

  • 你应该试试request.getRemoteHost()
  • 我在 IIS 中为我​​的 Coldfusion 网站禁用匿名登录,并在我的代码中使用此 (cgi.Auth_user) 来获取远程用户的用户名,在 Java 和 glassfish 中是否有类似的解决方法。跨度>
  • 要更清楚地了解这个问题,请参阅这个问题。 stackoverflow.com/questions/16032690/…

标签: java remote-access credentials


【解决方案1】:

您想做一些称为 SSO(单点登录)的事情:用户在某处登录(在您的情况下是他的 Windows 计算机)并且您希望使用此(已经完成的)登录来验证用户身份。这是一个非常常见的用例,并且有不同的方法可以做到这一点。但是,最大的问题始终是您如何信任这些第三方系统。这就是麻烦的开始。

由于您的问题不是很清楚,我假设您有一个在 Windows Server 上运行的 Java Glassfish 服务器和一个 Java 客户端(因为您要求提供 Java 代码)。因此 Java 服务器必须验证 Java 客户端的用户是谁。并且服务器必须信任这些信息。

使用System.getProperty("user.name"); 不是一个好主意,因为任何人都可以更改它。您可以使用java -Duser.name=Joe <your_program> 启动您的Java 程序,就是这样。

但由于您使用的是 Windows,因此您可以使用 Windows 来帮助您。如果您的客户端和服务器都在同一个域中,则它们将针对同一系统进行身份验证。您可以向该系统询问用户身份。通常公司的机器在同一个域中。

为此,有一个名为 Waffle 的工具。它在同一域中的计算机之间执行安全的 Windows 身份验证。如果您的客户端和服务器在同一个域中,那么执行 SSO(单点登录)是一种简单的方法。你可以在 GitHub 上找到它:http://dblock.github.io/waffle/

这是几个月前我自己的一个问题中的一个简单示例(请参阅here):

// client credentials handle
IWindowsCredentialsHandle credentials= WindowsCredentialsHandleImpl.getCurrent("Negotiate");
credentials.initialize();

// initial client security context
WindowsSecurityContextImpl clientContext = new WindowsSecurityContextImpl();
clientContext.setPrincipalName(Advapi32Util.getUserName());
clientContext.setCredentialsHandle(credentials.getHandle());
clientContext.setSecurityPackage(securityPackage);
clientContext.initialize();

// accept on the server
WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
IWindowsSecurityContext serverContext = null;

do {  

    if (serverContext != null) {

        // initialize on the client
        SecBufferDesc continueToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, serverContext.getToken());
        clientContext.initialize(clientContext.getHandle(), continueToken);
    }  

    // accept the token on the server
    serverContext = provider.acceptSecurityToken(clientContext.getToken(), "Negotiate");

} while (clientContext.getContinue() || serverContext.getContinue());

System.out.println(serverContext.getIdentity().getFqn());
for (IWindowsAccount group : serverContext.getIdentity().getGroups())
    System.out.println(" " + group.getFqn());        

您也可以将 Waffle 用于网站。但是,我没有这样做,也无法向您解释在这种情况下该怎么做。

还有一个重要的评论:我觉得你有点困惑。如果您在服务器上执行request.getRemoteHost(),您会尝试获取发送请求的客户端的身份(顺便说一下,它不安全,客户端可以发送任何内容)。但是,如果您在服务器上执行System.getProperty("user.name"),您会尝试获取服务器本身的名称。请注意您在哪里(在客户端或服务器上)以及您想要什么。并确保您是否可以信任此信息。安全性很困难。

【讨论】:

  • 嗨,Thomas,我不想使用 SSO,我只想知道他们登录的 Windows 机器的用户名。我不想使用外部工具,而且您提供的代码超出了我的范围,因为我是 java 新手。
  • 嗯,这是 SSO。您想通过他在 Windows 机器上使用的帐户来识别用户(= 获取其名称)。
  • 我想获取客户端的用户名,因为这个应用程序将只在我的组织中使用,所以我认为不会有安全问题。我在coldfusion中做到了,我通过cgi.remote_user获得了远程用户名,java中有类似的东西吗?请不要介意造句。
  • 如果我设置此代码,我添加对 jar 的引用,我能够编译我的 jar,但是在运行时,tomcat 抛出 Advautil32 无法解析,我需要将华夫饼罐放在哪里?谢谢
【解决方案2】:

java 类代码查找谁登录到域中的远程计算机

package com.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

import com.test.Pubfun;

public class UserName {
    public static HashMap <String,String> hmun=new HashMap<String, String>();
    public String setUserFromIP(String arg1) {
        String m = arg1;
        StringBuilder user = new StringBuilder();
        String u = "";
        String user2 = null;
        try {
            Process p = Runtime.getRuntime().exec("query user /server:" + m);
            p.waitFor();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    p.getInputStream()));
            String line = reader.readLine();
            while (line != null) {
                line = reader.readLine();
                user.append(line);              
                line=null;
            }

        } catch (IOException e1) {
        } catch (InterruptedException e2) {
        }   
        u = user.toString().replace("null", "");
        try {           
            user2 = this.getUserFromString(u);
        } catch (ArrayIndexOutOfBoundsException ae) {
        }
        u.replace("null", " "); 
        System.out.println(user2);      
        hmun.put("username",user2);
        return user2;
    }

    public static String gethmun()
    {
        String t=hmun.get("username");
        return t;
    }
    public String getUserFromString(String u) {
        HashMap <String,String> hmun=new HashMap<String, String>();
        String input = u;
        int length, size;
        length = input.length();
        size = length ;
        String strarray[] = new String[size];
        strarray = input.split("\\s+");     
        for (int i = 0; i < strarray.length; i++) {
            if(strarray[i].equals("Active")){
                hmun.put("username", strarray[i-3]);
            }

        }

        String user1=hmun.get("username");
        return user1;

    }
}

【讨论】:

    【解决方案3】:

    HttpServletRequest.getRemoteUser() 可以选择返回发出请求的用户的登录名(如果经过身份验证),但它不是在远程计算机上登录的用户的用户名。

    无法查询远程机器的用户名。发出请求的浏览器或应用程序可能会自愿发送此信息,但如果他们不这样做,您将无法找到获取它的方法。而且默认情况下他们不发送,所以不要指望这个。

    【讨论】:

      【解决方案4】:

      这将为您提供本地 Windows 系统 System.getProperty("user.name"); 的当前登录用户名

      【讨论】:

      • 他不需要当前JVM机器的用户信息。再看清楚问题。
      猜你喜欢
      • 2013-11-28
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 2013-04-19
      相关资源
      最近更新 更多