Ошибка 0x80005000 с LdapConnection и LDAPS

Перед тем, как начать, я уже посетил Неизвестную ошибку (0x80005000) с LDAPS Connection и изменил свой код, и, хотя он решил проблему, кажется, что он загадочным образом вернулся.

Вот хорошие вещи:

public static bool Authenticate(string username, string password, string domain)
{
    bool authentic = false;

    try
    {
        LdapConnection con = new LdapConnection(
            new LdapDirectoryIdentifier(Host, Port));
        if (IsSSL)
        {
            con.SessionOptions.SecureSocketLayer = true;
            con.SessionOptions.VerifyServerCertificate = ServerCallback;
        }
        con.Credential = new NetworkCredential(username, password);
        con.AuthType = AuthType.Basic;
        con.Bind();
        authentic = true;
    }
    catch (LdapException)
    {
        return false;
    }
    catch (DirectoryServicesCOMException)
    { }
    return authentic;
}

public static bool IsSSL
{
    get
    {
        return ConnectionString.ToLower().Contains("ldaps");
    }
}

public static string ConnectionString
{
    get
    {
        if (string.IsNullOrEmpty(_connectionString))
            _connectionString = CompleteConfiguration.GetLDAPConnectionString();

        return _connectionString;
    }
    set { _connectionString = value; }
}

public static int Port
{
    get
    {
        var x = new Uri(ConnectionString);
        int port = 0;
        if (x.Port != -1)
        {
            port = x.Port;
        }
        else
        {
            port = x.OriginalString.ToLower().Contains("ldaps")
                       ? 636
                       : 389;
        }
        return port;
    }
}

public static string Host
{
    get
    {
        var x = new Uri(ConnectionString);
        return x.Host;
    }
}

private static bool ServerCallback(LdapConnection connection, X509Certificate certificate)
{
    return true;
}

Вот плохие вещи: когда я пытаюсь пройти аутентификацию в приложении, я получаю следующую ошибку, если быть точным, она вызывается строкой con.Bind():

[COMException (0x80005000): неизвестная ошибка (0x80005000)] System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) +378094 System.DirectoryServices.DirectoryEntry.Bind() +36 System.DirectoryServices.DirectoryEntry.get_NativeObject().GCAuthentication.Authenticate(строковое имя пользователя, строковый пароль, строковый домен) в каталоге c:\Builds\6\Idealink.Open.Pancanal\ Панамский канал \Sources\Idealink.Open\Complete.Authentication\GCAuthentication.cs:27 Complete.Authentication.AuthenticationFactory.ValidateUserLdap(строковое имя пользователя, строковый пароль, строковый домен, логическое значение isValid, строковое имя пользователя WithDomain) в каталоге c:\Builds\6\Idealink.Open.Pancanal\ Панамский канал \ Sources \ Idealink.Open \ Complete.Autheory \ 93

Это довольно запутанно, поскольку кажется, что некоторые учетные записи пользователей работают, а другие нет. Однако, когда я размещаю приведенный выше код в изолированной тестовой среде, он успешно выполняется каждый раз, независимо от того, какую учетную запись я использую. Когда я помещаю его обратно на сервер Windows 2008 R2 с ASP.NET и IIS, происходит сбой, как указано выше. Отказы последовательны, хотя учетные записи постоянно терпят неудачу или преуспевают, с этой точки зрения нет случайности.

Доступ к LDAP-серверу должен осуществляться с использованием LDAPS, а НЕ LDAP, поэтому мы не можем использовать объект DirectoryEntry - LDAP-сервер контролируется клиентом и поэтому не может быть перенастроен или изменен каким-либо образом. Мы просто хотим записать имя пользователя / пароль в веб-форму, а затем использовать BIND на сервере LDAP для проверки учетных данных.

Мы используем.NET 3.5 и в настоящее время не можем выполнить обновление, поэтому я с уважением спрашиваю, если ваше основное предложение и аргументы должны быть обновлены, просим вас отложить ваш вклад.

Спасибо, надеюсь, вы можете помочь

1 ответ

Решение

Будет ли что-то вроде этой работы для вас..?

const string Domain = "ServerAddress:389";
const string constrParts = @"OU=Users,DC=domain,DC=com";
const string Username = @"karell";
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, Domain, constrParts);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext,  username);

Вот действительно хороший сайт для хороших ссылок и примеров DirectoryServices DirectoryEntry

для подключения через SSL вы можете сделать что-то вроде следующего

const int ldapInvalidCredentialsError = 0x31;
const string server = "your_domain.com:636";
const string domain = "your_domain.com";

try
{
    using (var ldapSSLConn = new LdapConnection(server))
    {
        var networkCredential = new NetworkCredential(username, password, domain);
        ldapSSLConn.SessionOptions.SecureSocketLayer = true;
        ldapSSLConn.AuthType = AuthType.Negotiate;
        ldapSSLConn.Bind(networkCredential);
    }

    // If the bind succeeds, the credentials are valid
    return true;
}
catch (LdapException ldapEx)
{
    // Invalid credentials a specific error code
    if (ldapEx.ErrorCode.Equals(ldapInvalidCredentialsError))
    {
        return false;
    }

    throw;
}

Список недействительных кодов ошибок LDAP в MSDN

Другие вопросы по тегам