验证Active Directory用户名和密码

时间:2016-11-15 12:39:23

标签: c# active-directory ldap directoryservices

 private static bool ValidateUser(string userName, string password, string ldapPath)
    {
        DirectoryEntry directoryEntry = new DirectoryEntry(ldapPath, userName, password, AuthenticationTypes.ReadonlyServer);
        try
        {
            object obj = directoryEntry.NativeObject;
            if (obj.IsNotNullRef())
            {
                return true;
            }
        }
        catch (Exception ex)
        {
            //error handling
        }
        finally
        {
            directoryEntry.Dispose();
        }
        return false;
    }

我上面的示例代码段验证了活动目录用户名&如果域NETBIOS和DNS匹配,则密码成功。

但是,如果域名(NETBIOS)与域的DNS条目不匹配,即NETBIOS& DNS的注册方式不同,即使您提供有效的用户名和密码,代码也不会返回true

我如何解决这个问题?

编辑:

示例输入只是标准输入,用户名,密码和输入。域名网址

  1. 返回True的示例:
  2. DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://abcd1.xyz1.xx1.org", "abcd1\\stacktrace1", "xxxx", AuthenticationTypes.ReadonlyServer);

    1. 返回false的示例:
    2. DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://abcd2.xyz2.xx2.org", "abcd2\\stacktrace2", "xxxx", AuthenticationTypes.ReadonlyServer);

      两个示例之间的唯一区别在于,在示例1中,域名(NETBIOS)与DNS条目匹配,而在示例2中,NETBIOS& DNS的注册方式不同。

1 个答案:

答案 0 :(得分:0)

参考以下方法:

public void AuthenticateUser(string userName, string password)
    {
        DirectoryUserAuthenticationResponse response = new DirectoryUserAuthenticationResponse();
        try
        {
            // Creating Principal Context.
            using (var principalContext = GetPrincipalContext())
            {
                try
                {
                    // Getting user identity and validating user against active provider.

                    var aUser = UserPrincipal.FindByIdentity(principalContext, GetIdentitytype(), userName);
                    if (aUser != null)
                    {
                        // To check user account is locked out or not
                        if (aUser.IsAccountLockedOut())
                            throw new Exception("UserAccountLockedOut");

                        // To check user account is disabled or not.
                        if (aUser.Enabled == false)
                            throw new Exception("UserAccountDisabled");

                        // To check user change password on next logon.
                        if (aUser.LastPasswordSet == null)
                            throw new Exception("changePassword");

                        //To check password expiration
                        if (aUser.LastPasswordSet != null && aUser.PasswordNeverExpires == false)
                        {
                            DirectoryEntry rootDSE = new DirectoryEntry("LDAP://" + _directoryServerInfo.IPAddress, userName, password);

                            try
                            {
                                // Bind to the ADsobject to force authentication
                                object nativeobject = rootDSE.Name;
                            }
                            catch (DirectoryServicesCOMException cex)
                            {
                                string errorCode = cex.ExtendedErrorMessage.Substring(cex.ExtendedErrorMessage.IndexOf("data", 1));
                                errorCode = errorCode.Substring(5, 3);
                                //The commented code below fails to parse properly and throws an exception 
                                // int exErrorCode = int.Parse(errorCode);
                                int exErrorCode = int.Parse(Regex.Match(errorCode, @"\d+").Value);
                                if (exErrorCode == (int)PWDFlags.Account_Expired)
                                    throw new Exception("AccountExpired");
                                if (exErrorCode == (int)PWDFlags.Password_Expiration)
                                    throw new Exception("PasswordExpired");
                            }
                        }
                        // validate the credentials by using principal context method.
                        var isAuthenticated = principalContext.ValidateCredentials(userName, password);
                        if (!isAuthenticated)
                        {
                            throw new Exception("Invalid your name and passowrd");
                        }
                    }
                    else
                        throw new Exception("InvalidUsernamePassword");
                }
                catch (DirectoryServicesCOMException cex)
                {
                    string errorCode = cex.ExtendedErrorMessage.Substring(cex.ExtendedErrorMessage.IndexOf("data", 1));
                    errorCode = errorCode.Substring(5, 3);
                    //The commented code below fails to parse properly and throws an exception 
                    // int exErrorCode = int.Parse(errorCode);
                    int exErrorCode = int.Parse(Regex.Match(errorCode, @"\d+").Value);
                    if (exErrorCode == (int)PWDFlags.Account_Expired)
                        throw new Exception("AdminACCExpire");
                    if (exErrorCode == (int)PWDFlags.Password_Expiration)
                        throw new Exception("AdminPWDExprire");
                    else
                    {
                      //Else any exception
                    }
                }
            }
        }
        catch (Exception)
        {
            throw;
        }

    }

   private PrincipalContext GetPrincipalContext()
    {


        // Creating Principal Context.
        PrincipalContext principalContext = null;
        string serveraddress = _directoryServerInfo.IPAddress;//+":"+_defdirectoryport ;

        if (string.IsNullOrEmpty(_directoryfilterouname))
        {

            principalContext = new PrincipalContext(ContextType.Domain, serveraddress, _directoryAdminUserId, _directoryAdminPassword);
            //principalContext = new PrincipalContext(ContextType.Domain, _directoryServerInfo.IPAddress , _directoryAdminUserId, _directoryAdminPassword);
        }
        else
        {
            //string domainComponents = GetDomainComponents();

            principalContext = new PrincipalContext(ContextType.Domain, serveraddress, _directoryfilterouname, _directoryAdminUserId, _directoryAdminPassword);
        }
        //// _directoryServerInfo.HostName = //((System.DirectoryServices.AccountManagement.ADStoreCtx)(principalContext.QueryCtx)).DnsDomainName;

        return principalContext;
    }