活动目录 – 检查用户名/密码

我在Windows Vista Ultimate SP1上使用以下代码来查询我们的活动目录服务器,以检查域上用户的用户名和密码。

public Object IsAuthenticated() { String domainAndUsername = strDomain + "\\" + strUser; DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, strPass); SearchResult result; try { //Bind to the native AdsObject to force authentication. DirectorySearcher search = new DirectorySearcher(entry) { Filter = ("(SAMAccountName=" + strUser + ")") }; search.PropertiesToLoad.Add("givenName"); // First Name search.PropertiesToLoad.Add("sn"); // Last Name search.PropertiesToLoad.Add("cn"); // Last Name result = search.FindOne(); if (null == result) { return null; } //Update the new path to the user in the directory. _path = result.Path; _filterAttribute = (String)result.Properties["cn"][0]; } catch (Exception ex) { return new Exception("Error authenticating user. " + ex.Message); } return user; } 

目标是使用.NET 3.5,并使用VS 2008标准进行编译

我使用的是正在运行应用程序的域pipe理员的域帐户login。

该代码在Windows XP上完美工作; 但在Vista上运行时,出现以下exception:

 System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password. at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.get_AdsObject() at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne) at System.DirectoryServices.DirectorySearcher.FindOne() at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated() at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.get_AdsObject() at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne) at System.DirectoryServices.DirectorySearcher.FindOne() at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated() 

我试过改变authenticationtypes,我不知道发生了什么事情。


另请参阅 : 根据Active Directoryvalidation用户名和密码?

如果您使用.net 3.5,请改用此代码。

要authentication用户:

 PrincipalContext adContext = new PrincipalContext(ContextType.Domain); using (adContext) { return adContext.ValidateCredentials(UserName, Password); } 

如果你需要find用户对象的R / W属性,可以这样做:

 PrincipalContext context = new PrincipalContext(ContextType.Domain); UserPrincipal foundUser = UserPrincipal.FindByIdentity(context, "jdoe"); 

这是使用System.DirectoryServices.AccountManagement命名空间,因此您需要将其添加到您的使用语句。

如果您需要将UserPrincipal对象转换为DirectoryEntry对象以使用旧版代码,则可以这样做:

 DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject(); 

我发现在多个网站上的互联网上漂浮着相同的代码,并没有为我工作。 Steve Evans可能是正确的,如果你使用.NET 3.5,你不应该使用这个代码。 但是,如果你仍然在.NET 2.0上,你可以试试这个来validation你的AD服务:

 DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, userName, password, AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer); object nativeObject = entry.NativeObject; 

第一行使用域,用户名和密码创build一个DirectoryEntry对象。 它还设置了AuthenticationTypes。 请注意,我如何使用两个参数之间的“按位或”(“|')运算符来设置安全(Kerberos)身份validation和SSL。

第二行强制使用来自第一行的信息将“entry”的NativeObject绑定到AD服务。

如果抛出exception,那么证书(或设置)是不好的。 如果没有例外,你是通过身份validation。 exception消息通常会指示出了什么问题。

这段代码与您已有的代码非常相似,但是在有“path”的地方使用该域,并且用户名不与域组合。 一定要正确设置您的AuthenticationTypes。 这可能会造成或破坏身份validation的能力。

无论如何,我想通了如果你在域名与Vista的用户名​​传递它不像“域\用户”,所以只是传递“用户”而不是似乎工作正常 – 除了你必须在同一个域

绑定到LDAP需要特权提升(UAC)? 您可以尝试以pipe理员身份运行Visual Studio和/或应用程序,看看是否有帮助。 如果这是个问题,你可以随时在应用程序中添加一个清单,并将其设置为需要提升,这样当用户运行时就会提示。

不知道为什么这将需要提高特权,但它是值得一试。