我希望我的桌面Java应用程序能够与Active Directory用户进行单点登录.分两步,我想:
使用Java:确定当前Windows用户的程序方法我可以获得当前Windows用户的名称,但我可以依赖它吗?我觉得
System.getProperty("user.name")
Run Code Online (Sandbox Code Playgroud)
会不够安全?("user.name"似乎来自环境变量,所以我不能依赖它,我想?)
问题在Linux上使用Java对Active Directory进行 身份验证为我提供了给定名称+ pass的身份验证,但我想根据Windows登录进行身份验证?
对于Active Directory访问,LDAP可能是选择?
我不完全确定我是否提出了正确的问题,但希望有人有一些想法可以转发我.
有人问过,并回答过.NET,但是现在是时候得到原生Win32代码的答案了:
如何验证Windows用户名和密码?
我之前问过托管代码这个问题.现在是原生解决方案的时候了.
需要指出一些更常见的解决方案的陷阱:
很多人建议查询Active Directory.如果抛出异常,那么您知道凭据无效 - 正如此stackoverflow问题中所建议的那样.
您不仅要对域帐户进行身份验证,还要进行隐式授权检查.也就是说,您正在使用模拟令牌从AD中读取属性.如果其他有效帐户无权从AD读取,该怎么办?默认情况下,所有用户都具有读取权限,但可以将域策略设置为禁用受限帐户(和/或组)的访问权限.
绑定AD会产生严重的开销,必须在客户端加载AD架构缓存(DirectoryServices使用的ADSI提供程序中的ADSI缓存).这既是网络又是AD服务器,消耗资源 - 而且对于像验证用户帐户这样的简单操作来说太昂贵了.
您依赖于非例外情况的异常失败,并假设这意味着无效的用户名和密码.然后,其他问题(例如,网络故障,AD连接故障,内存分配错误等)被错误地表示为身份验证失败.
使用DirectoryEntry该类是.NET是验证凭据的错误方法的示例:
无效的方法1a - .NET
DirectoryEntry entry = new DirectoryEntry("persuis", "iboyd", "Tr0ub4dor&3");
object nativeObject = entry.NativeObject;
Run Code Online (Sandbox Code Playgroud)
无效的方法1b - .NET#2
public static Boolean CheckADUserCredentials(String accountName, String password, String domain)
{
Boolean result;
using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, accountName, password))
{
using (DirectorySearcher searcher = new DirectorySearcher(entry))
{ …Run Code Online (Sandbox Code Playgroud) 我被要求在现有客户端服务器应用程序中针对Active Directory对用户进行身份验证提供支持.
此时,用户从客户端计算机提供用户名和密码,通过线路(加密)传递到我们的服务器进程,并与存储在数据库中的用户名/密码进行匹配.
最初,我认为这将是一个容易解决的问题,因为我可以简单地从我们的服务器进程中针对Active Directory验证用户的名称/密码.但事实证明,用户不必从我们的客户端应用程序输入密码,而是从当前的Windows登录会话中获取其凭据.
我现在面临的问题是如何在没有密码的情况下使用Active Directory进行身份验证? 我确信必须有一种方法可以某种方式将某种"令牌"从客户端传递到我们的服务器进程,这可以用作另一种身份验证方法,但到目前为止我的研究已经画了一个空白.
我们的服务器是用C++编写的,所以我们将使用win32 API.我还打算使用运行Windows 2008 AD LDS的虚拟机来开发和调试它- 我希望这对我想要实现的目标是足够的.
非常感谢任何帮助或建议.
我需要使用他们的用户名验证公司中的用户 - 而不是他们的密码.
所以我需要一个像这样的方法
public bool UserExists(string username)
{ ... }
Run Code Online (Sandbox Code Playgroud)
我知道System.DirectoryServices命名空间但不知道从哪里开始.
有任何想法吗?
有80,000多条记录,所以请记住这一点.
谢谢.
编辑:
我做到了 - 我的代码是:
private bool UserExists(string userName, string domain)
{
try
{
DirectoryEntry.Exists("WinNT://" + domain + ".[hidden].com/" + userName);
return true;
}
catch (COMException)
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道它是否正确,但它似乎到目前为止工作.
迈克尔的答案有两个相关部分:
更新#2:
我实际上用过这个:
public static bool LoggedOnUserExists()
{
var domain = new PrincipalContext(ContextType.Domain);
UserPrincipal foundUser = UserPrincipal.FindByIdentity(domain, IdentityType.SamAccountName, Environment.UserName);
return foundUser != null;
}
Run Code Online (Sandbox Code Playgroud)