问题 如何在.NET中验证LDAP


我想在Windows操作系统上使用任何目录服务验证我的应用程序的用户名和密码。例如,它可以是microsoft active directory,Novell eDirecotry或SunOne。我已经知道如何使用c#本地为Microsoft Active Direcotry执行此代码。 (我完全放弃使用ADSI并创建一个低级别的com组件)

尝试使用Novel eDirecotory进行身份验证的方式是我安装了Mono项目。在单声道项目中,它们为您提供Novell.Directory.ldap.dll代码看起来与Microsoft Active Directory相同。(http://www.novell.com/coolsolutions/feature/11204.html

对于SunOne,我被告知使用与活动目录相同的代码,但是ldap connecton字符串有点不同。(http://forums.asp.net/t/354314.aspx) (http://technet.microsoft.com/en-us/library/cc720649.aspx

为了使我的项目复杂化,大多数客户使用“服务帐户:”,这意味着我需要使用管理用户名和密码绑定,然后才能验证常规用户名和密码。我的问题分为两部分。

1)根据我上面所解释的,这是我应该针对每个单独的服务进行身份验证的正确方向吗?

2)我觉得我根本不需要做任何这些代码。我也觉得使用服务帐户的规定并不重要。如果我关心的是在Windows机器上验证用户名和密码,为什么我甚至需要使用ldap?我想说的是,考虑一下。当您在早上登录计算机时,您无需提供服务帐户即可登录。我可以通过使用runas功能在DOS提示符下轻松验证用户名和密码,我将被拒绝或无法解析文本文件。我确定还有其他方法可以将用户名和密码传递给我所在的Windows操作系统,并告诉我用户名和密码是否对其所在的域有效。我对吗?如果是这样,你们有什么建议方法?

Michael Evanchik www.MikeEvanchik.com


4958
2018-04-20 17:23


起源



答案:


所有这些都可以使用System.DirectoryServices.Protocols完成。如果您为目录创建LdapConnection,则可以使用服务帐户进行绑定,然后进行后续绑定以验证凭据。

服务帐户通常用于限制对服务器的身份验证机制的访问。这样,街上没有随机的人可以尝试使用您的LDAP服务器进行身份验证。

此外,您是否希望每位用户在登录时都能提供其专有名称?对于Active Directory,只需要sAMAccountName,而eDirectory和SunONE等其他提供程序需要使用专有名称进行身份验证。

要执行此类型的身份验证,您需要使用提供的服务帐户对服务器进行身份验证,搜索具有给定用户名的用户,并获取该用户的可分辨名称。然后,您可以使用该专有名称和提供的密码进行身份验证。

这适用于所有LDAP系统,但Active Directory除外,它只对sAMAccountName感到满意。


3
2018-05-07 19:54





我不确定我是否完全理解这个问题,但在某些情况下,我发现通过简单地搜索他们的帐户并使用他们的凭据作为用户名和密码来验证用户很容易。

成功的查询意味着提供的所有内容都是正确的,找不到帐户意味着出错。

//use the users credentials for the query
DirectoryEntry root = new DirectoryEntry(
    "LDAP://dc=domain,dc=com", 
    loginUser, 
    loginPassword
    );

//query for the username provided
DirectorySearcher searcher = new DirectorySearcher(
    root, 
    "(sAMAccountName=" + loginUser + ")"
    );    

//a success means the password was right
bool success = false; 
try {
    searcher.FindOne();
    success = true;
}
catch {
    success = false;
}

可能不是“最佳实践”,但可能会解决您遇到的问题......


11
2018-04-20 17:36



我假设上面只是微软AD,并且正在使用LDAP。谢谢你的代码。我的问题更多的是通用的方式,可能不使用LDAP,因为一些LDAP服务器需要服务帐户用户名和密码,只是为了绑定,所以你甚至可以尝试验证普通用户。 - Michael Rudner Evanchik
这就是我的建议 - 使用登录用户的凭据(假设您要求他们的用户名和密码)作为服务帐户。应该至少能够查询和查看自己的帐户。如果有效则您知道身份验证有效。这似乎是一种检查密码是否正确的相当通用的方法。 - Hugoware


答案:


所有这些都可以使用System.DirectoryServices.Protocols完成。如果您为目录创建LdapConnection,则可以使用服务帐户进行绑定,然后进行后续绑定以验证凭据。

服务帐户通常用于限制对服务器的身份验证机制的访问。这样,街上没有随机的人可以尝试使用您的LDAP服务器进行身份验证。

此外,您是否希望每位用户在登录时都能提供其专有名称?对于Active Directory,只需要sAMAccountName,而eDirectory和SunONE等其他提供程序需要使用专有名称进行身份验证。

要执行此类型的身份验证,您需要使用提供的服务帐户对服务器进行身份验证,搜索具有给定用户名的用户,并获取该用户的可分辨名称。然后,您可以使用该专有名称和提供的密码进行身份验证。

这适用于所有LDAP系统,但Active Directory除外,它只对sAMAccountName感到满意。


3
2018-05-07 19:54





我不确定我是否完全理解这个问题,但在某些情况下,我发现通过简单地搜索他们的帐户并使用他们的凭据作为用户名和密码来验证用户很容易。

成功的查询意味着提供的所有内容都是正确的,找不到帐户意味着出错。

//use the users credentials for the query
DirectoryEntry root = new DirectoryEntry(
    "LDAP://dc=domain,dc=com", 
    loginUser, 
    loginPassword
    );

//query for the username provided
DirectorySearcher searcher = new DirectorySearcher(
    root, 
    "(sAMAccountName=" + loginUser + ")"
    );    

//a success means the password was right
bool success = false; 
try {
    searcher.FindOne();
    success = true;
}
catch {
    success = false;
}

可能不是“最佳实践”,但可能会解决您遇到的问题......


11
2018-04-20 17:36



我假设上面只是微软AD,并且正在使用LDAP。谢谢你的代码。我的问题更多的是通用的方式,可能不使用LDAP,因为一些LDAP服务器需要服务帐户用户名和密码,只是为了绑定,所以你甚至可以尝试验证普通用户。 - Michael Rudner Evanchik
这就是我的建议 - 使用登录用户的凭据(假设您要求他们的用户名和密码)作为服务帐户。应该至少能够查询和查看自己的帐户。如果有效则您知道身份验证有效。这似乎是一种检查密码是否正确的相当通用的方法。 - Hugoware


我们有一个网站需要根据域凭据验证用户名和密码,并使用LogonUser API函数。使用它进行网络登录(其中一个参数是登录类型),它所做的只是验证凭据,它不会像加载runas那样的用户配置文件。 唯一需要注意的是服务帐户确实需要足够的访问权来调用LogonUser。我建议您检查MSDN文档中的访问权限,因为它因操作系统而异。


0
2018-04-20 17:54



谢谢你带领我走正确的道路。虽然你的权利,你需要本地管理员才能进行这个api调用,谷歌搜索的东西,如果你读这个帖子,他们说有一个api调用,不需要这个 vbforums.com/showthread.php?t=240277   AcquireCredentialsHandleNT with在security.dll中 - Michael Rudner Evanchik
如果您在2003年,那么LogonUser不需要SE_TCB_NAME。我不认为只是调用AcquireCredentialsHandle会检查它们是否有效。该代码模拟完整的客户端/服务器身份验证检查。除了显而易见的代码之外,看不出有什么问题。 - pipTheGeek