C# Active Directory - 检查用户名/密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/400872/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:02:29  来源:igfitidea点击:

Active Directory - Check username / password

c#windows-vistaactive-directoryldap

提问by Michael G

I'm using the following code on Windows Vista Ultimate SP1 to query our active directory server to check the user name and password of a user on a domain.

我在 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;
}

the target is using .NET 3.5, and compiled with VS 2008 standard

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

I'm logged in under a domain account that is a domain admin where the application is running.

我使用域帐户登录,该帐户是运行应用程序的域管理员。

The code works perfectly on windows XP; but i get the following exception when running it on Vista:

该代码在 Windows XP 上完美运行;但是在 Vista 上运行时出现以下异常:

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()

I've tried changing the authentication types, I'm not sure what's going on.

我尝试更改身份验证类型,但不确定发生了什么。



See also: Validate a username and password against Active Directory?

另见针对 Active Directory 验证用户名和密码?

采纳答案by Steve Evans

If you're using .net 3.5 use this code instead.

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

To authenticate a user:

要验证用户:

PrincipalContext adContext = new PrincipalContext(ContextType.Domain);

using (adContext)
{
     return adContext.ValidateCredentials(UserName, Password);
}

If you need to find the user to R/W attributes to the object do this:

如果您需要查找对象的 R/W 属性,请执行以下操作:

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

This is using the System.DirectoryServices.AccountManagement namespace so you'll need to add it to your using statements.

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

If you need to convert a UserPrincipal object to a DirectoryEntry object to work with legacy code you can do this:

如果您需要将 UserPrincipal 对象转换为 DirectoryEntry 对象以使用遗留代码,您可以执行以下操作:

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

回答by Steven Robbins

Does binding to LDAP require elevated privs (UAC)? You could try running Visual Studio and/or the app as Administrator and see if that helps. If that's the problem you could always add a manifest to the application and set it to require elevation, that way it will prompt when a user runs it.

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

Not sure why it would require elevated privs, but it's worth a shot.

不知道为什么它需要提升权限,但值得一试。

回答by Michael G

I figured it out anyhow If you pass in the domain with the username on vista it does not work like "domain\user" so just passing "user" instead seems to work okay - except you have to be on the same domain

无论如何我想通了如果你在vista上使用用户名传入域,它不像“域\用户”那样工作,所以只传递“用户”似乎可以正常工作 - 除非你必须在同一个域中

回答by Pretzel

I found that same code floating around the Internet on multiple websites and it didn't work for me. Steve Evans is probably right that if you're on .NET 3.5, you should not use this code. But if you ARE still on .NET 2.0 you can try this to Authenticate to your AD services:

我发现相同的代码在多个网站上漂浮在互联网上,但对我不起作用。Steve Evans 可能是对的,如果您使用的是 .NET 3.5,则不应使用此代码。但是,如果您仍在使用 .NET 2.0,您可以尝试使用以下方法对您的 AD 服务进行身份验证:

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

The first line creates a DirectoryEntry object using domain, username, and password. It also sets the AuthenticationTypes. Notice how I'm setting both Secure (Kerberos) Authentication and SSL using the "Bitwise OR" ( '|' ) operator between the two parameters.

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

The second line forces the NativeObject of "entry" to Bind to the AD services using the information from the first line.

第二行使用第一行中的信息强制“条目”的 NativeObject 绑定到 AD 服务。

If an exception is thrown, then the credentials (or settings) were bad. If no exception, you're authenticated. The exception message will usually indicate what went wrong.

如果抛出异常,则凭据(或设置)是错误的。如果没有例外,则您已通过身份验证。异常消息通常会指出哪里出了问题。

This code is pretty similar to what you already have, but the domain is used where you have "path", and the username is not combined with the domain. Be sure to set your AuthenticationTypes properly, too. This can make or break the ability to authenticate.

此代码与您已有的代码非常相似,但域用于您具有“路径”的位置,并且用户名未与域组合。确保也正确设置您的 AuthenticationTypes。这可以成就或破坏身份验证的能力。