C# 如何在 .NET 中验证 LDAP
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/769268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Authenticate LDAP in .NET
提问by Michael Rudner Evanchik
I would like to authenticate username and passwords for my application on a windows operating system with any directory service. For example it could be microsoft active directory, Novell eDirecotry, or SunOne. I already know how to do this code natively for Microsoft Active Direcotry with c#. ( I totally gave up using ADSI and creating a low level com component)
我想在具有任何目录服务的 Windows 操作系统上验证我的应用程序的用户名和密码。例如,它可以是 microsoft active directory、Novell eDirecotry 或 SunOne。我已经知道如何使用 c# 为 Microsoft Active Direcotry 本地执行此代码。(我完全放弃使用 ADSI 并创建一个低级 com 组件)
The way im attempting to authenticate with Novel eDirecotory is i have installed the Mono project. Inside the mono project they provide you with Novell.Directory.ldap.dll The code looks somewhat the same as for Microsoft Active Directory.(http://www.novell.com/coolsolutions/feature/11204.html)
我尝试使用 Novel eDirecotor 进行身份验证的方式是我已经安装了 Mono 项目。在 mono 项目中,他们为您提供 Novell.Directory.ldap.dll 代码看起来与 Microsoft Active Directory 有点相同。(http://www.novell.com/coolsolutions/feature/11204.html)
For SunOne, i have been told to use the same code as active direcotry, but the ldap connecton string is a little different.(http://forums.asp.net/t/354314.aspx) (http://technet.microsoft.com/en-us/library/cc720649.aspx)
对于 SunOne,我被告知使用与 active direcotry 相同的代码,但 ldap 连接字符串略有不同。( http://forums.asp.net/t/354314.aspx) ( http://technet. microsoft.com/en-us/library/cc720649.aspx)
To complicate my project, most customers use a "Service account:" which means i need to bind with an administrative username and password before i can authenticate a regular username and password. My questions is in 2 parts.
为了使我的项目复杂化,大多数客户使用“服务帐户:”这意味着我需要绑定管理用户名和密码,然后才能对常规用户名和密码进行身份验证。我的问题分为两部分。
1) From what I have explained above, is this the correct direction I should be going to authenticate against each individual direcotory service?
1)根据我上面的解释,这是我应该针对每个单独的目录服务进行身份验证的正确方向吗?
2) I feel that i dont not need to do any of this code at all. I also feel the stipulation of using a service account is not imporant at all. If all I care about is authenticating a username and password on a windows machine why do i even need to use ldap? I mean think about it. When you login to your machine in the morning, you do not have to provide a service account just to login. I can easily authenticate a username and password at a DOS prompt by using the runas feature and i will be denied or not and could parse the text file. Im sure there are other ways i could pass a username and password to the windows operating system that i am on and will tell me if a username and password is valid for the domain that it is on. Am i right? If so what suggested ways do you guys have?
2)我觉得我根本不需要做任何这些代码。我也觉得使用服务帐户的规定根本不重要。如果我只关心在 Windows 机器上验证用户名和密码,为什么我什至需要使用 ldap?我想说的是,考虑一下。当您早上登录到您的机器时,您无需提供服务帐户即可登录。我可以使用 runas 功能在 DOS 提示符下轻松验证用户名和密码,我将被拒绝或不会被拒绝,并且可以解析文本文件。我确定还有其他方法可以将用户名和密码传递给我所在的 Windows 操作系统,并且会告诉我用户名和密码对于它所在的域是否有效。我对吗?如果是这样,你们有什么建议的方法?
Michael Evanchik www.MikeEvanchik.com
迈克尔·埃文奇克 www.MikeEvanchik.com
采纳答案by Jared
All this can be done with System.DirectoryServices.Protocols. If you create an LdapConnection to the directory you can use the service account to bind with, and then make a subsequent bind to authenticate the credentials.
所有这些都可以通过 System.DirectoryServices.Protocols 来完成。如果您创建到目录的 LdapConnection,您可以使用服务帐户进行绑定,然后进行后续绑定以验证凭据。
The service account is generally used to limit access to the authentication mechanism of the server. This way no random person on the street can try to auth with your LDAP server.
服务帐号一般用于限制对服务器的认证机制的访问。这样,街上的任何人都无法尝试使用您的 LDAP 服务器进行身份验证。
Also, do you expect that each user will provide their distinguished name when logging in? With Active Directory, only the sAMAccountName is required, yet other providers like eDirectory and SunONE require the distinguished name for authentication.
另外,您是否希望每个用户在登录时都提供其专有名称?对于 Active Directory,只需要 sAMAccountName,而其他提供商(如 eDirectory 和 SunONE)则需要可分辨名称进行身份验证。
To perform this type of authentication, you would need to use the service account that is provided to authenticate to the server, perform a search for a user with the given username, and grab that users distinguished name. You can then authenticate using that distinguished name and the password that was provided.
要执行这种类型的身份验证,您需要使用提供的服务帐户对服务器进行身份验证,使用给定的用户名搜索用户,并获取该用户的专有名称。然后,您可以使用该专有名称和提供的密码进行身份验证。
This will work for all LDAP systems, with the exception of Active Directory which will be happy with just the sAMAccountName.
这将适用于所有 LDAP 系统,但 Active Directory 除外,它只会对 sAMAccountName 感到满意。
回答by Hugoware
I'm not sure I entirely understand the question, but in some situations I've found it easy to authenticate a user by simply doing a search for their account and using their credentials as the username and password.
我不确定我是否完全理解这个问题,但在某些情况下,我发现只需搜索他们的帐户并使用他们的凭据作为用户名和密码,就可以轻松验证用户的身份。
A successful query means everything provided was correct, not finding the account means something was wrong.
成功的查询意味着提供的一切都是正确的,没有找到帐户意味着有问题。
//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;
}
Probably not "best practice", but might get around your issue you are having...
可能不是“最佳实践”,但可能会解决您遇到的问题......
回答by pipTheGeek
We had a website that needed to authenticate a username and password against domain credentials and used the LogonUser API function. Use it for a network logon (one of its arguments is logon type) and all it does is validate credentials, it doesn't do things like load the users profile that runas would. Only caveat is that the service account does require sufficient access to call LogonUser. I suggest you check the MSDN documentation for what that access is though because it varies by OS.
我们有一个网站需要根据域凭据对用户名和密码进行身份验证,并使用了 LogonUser API 函数。将它用于网络登录(它的参数之一是登录类型),它所做的只是验证凭据,它不会像 runas 那样加载用户配置文件。唯一需要注意的是,服务帐户确实需要足够的访问权限才能调用 LogonUser。我建议您查看 MSDN 文档以了解该访问权限是什么,因为它因操作系统而异。