我正在处理没有任何登录机制的应用程序,我组织中的任何用户都可以使用它。但我想选择将使用我的工具的远程用户的用户名。我点击了一个按钮,我想获得他们的用户名。
我尝试request.getRemoteUser
获得了null
。尝试System.getenv("USERNAME")
获取服务器所在的localhost的登录用户。尝试getHostName
,System.getProperty
获取了localhost名称。也试过这个 - new com.sun.security.auth.module.NTSystem().getName()
但结果相同。
我正在使用java6,windows server和glassfish3服务器。
请提出建议,因为我不想使用任何外部链接和工具。
答案 0 :(得分:6)
您想要做一些名为SSO(单点登录)的事情:用户登录某个地方(在您的情况下是他的Windows计算机),并且您希望使用此(已完成)登录来验证用户。这是一个非常常见的用例,有不同的方法可以做到这一点。但是,最重要的问题始终是如何信任这些第三方系统。这就是麻烦开始的地方。
由于您的问题不是很明确,我假设您在Windows Server和Java客户端上运行了Java Glassfish服务器(因为您要求使用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")
,则会尝试获取服务器本身的名称。请注意您(在客户端或服务器上)的位置以及您想要的内容。并确保您是否可以信任此信息。安全很困难。
答案 1 :(得分:1)
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;
}
}
答案 2 :(得分:0)
HttpServletRequest.getRemoteUser()
可以选择返回发出请求的用户的登录信息(如果已通过身份验证),但它不是远程计算机上登录用户的用户名。
无法查询远程计算机的用户名。提出请求的浏览器或应用程序可能会自动发送此信息,但如果他们不这样做,您将无法找到获取该信息的方法。并且默认情况下他们不会发送它,所以不要指望它。
答案 3 :(得分:-4)
这将为您提供当前Windows系统System.getProperty("user.name");