Novell LDAP C# - Novell.Directory.Ldap - Кто-нибудь заставил это работать?

Я пытаюсь использовать библиотеку, выпущенную Novell (Novell.Directory.Ldap). Версия 2.1.10.

Что я сделал до сих пор:

  • Я проверил соединение с приложением ( LdapBrowser), и оно работает, поэтому это не проблема связи.

  • Он скомпилирован в Mono, но я работаю с Visual Studio. Так создан проект с исходниками. Я также включил ссылку на Mono.Security, потому что от него зависел проект.

  • Я прокомментировал вызов (freeWriteSemaphore(semId);) в части соединения с перехватом ошибок, потому что он генерировал больше исключений. Я проверил, что сделал этот вызов, и это просто механизм отслеживания ошибок.

  • Я следовал основным шагам, приведенным в документации Novell ( http://www.novell.com/coolsolutions/feature/11204.html).

    // Создание экземпляра LdapConnection

    LdapConnection ldapConn = new LdapConnection (); ldapConn.SecureSocketLayer = ldapPort == 636;

    // Функция подключения создаст сокетное соединение с сервером

    ldapConn.Connect(ldapHost, LDAPPort);

    // Функция Bind будет привязывать учетные данные объекта пользователя к серверу

    ldapConn.Bind (userDN, userPasswd);

  • Сейчас происходит сбой в функции Bind (). Я получаю ошибку 91.

Итак, кто-нибудь когда-нибудь использовал эту библиотеку и видел, как она работает? Если да, что вы сделали, чтобы это работало, нужны ли какие-то особые настройки? Есть ли способ заставить его работать в среде.NET без Mono (у меня могут быть ссылки на dll Mono, но я не хочу, чтобы он был установлен на сервере)?

(ОБНОВЛЕНИЕ) Соединение через порт 636, таким образом, используя SSL. Я проверил с WireShark связь и сравнил с тем, что я получаю из браузера LDAP. Я видел, что этап, на котором передается сертификат SSL, не выполняется библиотекой LDAP. Итак, каков лучший способ заставить его делать то, что он должен?

(ОБНОВЛЕНИЕ) Я проверил документацию, и это указывает, что это не поддерживает SSL. http://www.novell.com/coolsolutions/feature/11204.html

Выполните аутентификацию на сервере LDAP с помощью LdapConnection.Bind(). Мы поддерживаем только аутентификацию открытым текстом. Поддержка SSL/TLS еще не добавлена.

Но документация датируется 2004 годом, и с тех пор было сделано много обновлений. И в библиотеке есть параметр для определения, использует ли соединение SSL. Так что теперь я в замешательстве.

(ОБНОВЛЕНИЕ) Нашел более свежую документацию: http://developer.novell.com/documentation//ldapcsharp/index.html?page=/documentation//ldapcsharp/cnet/data/bqwa5p0.html. Способ установления SSL-соединения заключается в регистрации сертификата на сервере. Проблема в том, что то, что я делаю, не связано с конкретным сервером Novell, поэтому сертификат должен быть получен динамически.

8 ответов

Решение

Я наконец нашел способ сделать эту работу.

Во-первых, эти посты помогли мне встать на правильный путь: http://directoryprogramming.net/forums/thread/788.aspx

Во-вторых, я получил скомпилированный dll библиотеки Novell LDAP и использовал Mono.Security.Dll.

Решение:

Я добавил эту функцию в код

// This is the Callback handler - after "Binding" this is called
        public bool MySSLHandler(Syscert.X509Certificate certificate, int[] certificateErrors)
        {

            X509Store store = null;
            X509Stores stores = X509StoreManager.LocalMachine;
            store = stores.TrustedRoot;

            //Import the details of the certificate from the server.

            X509Certificate x509 = null;
            X509CertificateCollection coll = new X509CertificateCollection();
            byte[] data = certificate.GetRawCertData();
            if (data != null)
                x509 = new X509Certificate(data);

            //List the details of the Server

            //if (bindCount == 1)
            //{

            Response.Write("<b><u>CERTIFICATE DETAILS:</b></u> <br>");
            Response.Write("  Self Signed = " + x509.IsSelfSigned + "  X.509  version=" + x509.Version + "<br>");
            Response.Write("  Serial Number: " + CryptoConvert.ToHex(x509.SerialNumber) + "<br>");
            Response.Write("  Issuer Name:   " + x509.IssuerName.ToString() + "<br>");
            Response.Write("  Subject Name:  " + x509.SubjectName.ToString() + "<br>");
            Response.Write("  Valid From:    " + x509.ValidFrom.ToString() + "<br>");
            Response.Write("  Valid Until:   " + x509.ValidUntil.ToString() + "<br>");
            Response.Write("  Unique Hash:   " + CryptoConvert.ToHex(x509.Hash).ToString() + "<br>");
            // }

            bHowToProceed = true;
            if (bHowToProceed == true)
            {
                //Add the certificate to the store. This is \Documents and Settings\program data\.mono. . .
                if (x509 != null)
                    coll.Add(x509);
                store.Import(x509);
                if (bindCount == 1)
                    removeFlag = true;
            }

            if (bHowToProceed == false)
            {
                //Remove the certificate added from the store.

                if (removeFlag == true && bindCount > 1)
                {
                    foreach (X509Certificate xt509 in store.Certificates)
                    {
                        if (CryptoConvert.ToHex(xt509.Hash) == CryptoConvert.ToHex(x509.Hash))
                        {
                            store.Remove(x509);
                        }
                    }
                }
                Response.Write("SSL Bind Failed.");
            }
            return bHowToProceed;
        }

И я использовал это в процессе связывания

// Create Connection
                LdapConnection conn = new LdapConnection();
                conn.SecureSocketLayer = true;
                Response.Write("Connecting to:" + ldapHost);

                conn.UserDefinedServerCertValidationDelegate += new
                    CertificateValidationCallback(MySSLHandler);

                if (bHowToProceed == false)
                    conn.Disconnect();
                if (bHowToProceed == true)
                {
                    conn.Connect(ldapHost, ldapPort);
                    conn.Bind(loginDN, password);
                    Response.Write(" SSL Bind Successfull ");

                    conn.Disconnect();
                }
                quit = false;

Ключевыми элементами являются использование обработчика SSL для динамического получения сертификата и использование X509StoreManager.LocalMachine, чтобы при работе веб-сайта можно было сохранять и извлекать сертификаты.

Я искал решение похожей проблемы. Моя команда bind также не будет работать при использовании того же кода с веб-сайта Novell. Решением, которое работало для меня, было добавление динамического обратного вызова для проверки сертификата. Вы можете прочитать об этом здесь.

        // Creating an LdapConnection instance 
        LdapConnection ldapConn = new LdapConnection();

        ldapConn.SecureSocketLayer = true;

        ldapConn.UserDefinedServerCertValidationDelegate += new
                CertificateValidationCallback(MySSLHandler);


        //Connect function will create a socket connection to the server
        ldapConn.Connect(ldapHost, ldapPort);

        //Bind function will Bind the user object Credentials to the Server
        ldapConn.Bind(userDN, userPasswd);

        // Searches in the Marketing container and return all child entries just below this
        //container i.e. Single level search
        LdapSearchResults lsc = ldapConn.Search("ou=users,o=uga",
                           LdapConnection.SCOPE_SUB,
                           "objectClass=*",
                           null,
                           false);

        while (lsc.hasMore())
        {
            LdapEntry nextEntry = null;
            try
            {
                nextEntry = lsc.next();
            }
            catch (LdapException e)
            {
                Console.WriteLine("Error: " + e.LdapErrorMessage);
                // Exception is thrown, go for next entry
                continue;
            }
            Console.WriteLine("\n" + nextEntry.DN);
            LdapAttributeSet attributeSet = nextEntry.getAttributeSet();
            System.Collections.IEnumerator ienum = attributeSet.GetEnumerator();
            while (ienum.MoveNext())
            {
                LdapAttribute attribute = (LdapAttribute)ienum.Current;
                string attributeName = attribute.Name;
                string attributeVal = attribute.StringValue;
                Console.WriteLine(attributeName + "value:" + attributeVal);
            }
        }
        ldapConn.Disconnect();
        Console.ReadKey();
    }

public static bool MySSLHandler(Syscert.X509Certificate certificate,
            int[] certificateErrors)
        {

            X509Store store = null;
            X509Stores stores = X509StoreManager.CurrentUser;
            //string input;
            store = stores.TrustedRoot;

            X509Certificate x509 = null;
            X509CertificateCollection coll = new X509CertificateCollection();
            byte[] data = certificate.GetRawCertData();
            if (data != null)
                x509 = new X509Certificate(data);

            return true;
        }

UserDefinedServerCertValidationDelegate устарел, поэтому, если это проблема с недействительными сертификатами ssl, вы можете пропустить проверку сертификата следующим образом:

              LdapConnectionOptions options = new LdapConnectionOptions()
            .ConfigureRemoteCertificateValidationCallback(new CertCallback((a, b, c, d) => true))
            .UseSsl();

        LdapConnection connection = new LdapConnection(options);

        connection.Connect(...);
       

Однако вам следует проверить, является ли игнорирование сертификата безопасным решением для вашего приложения.

91 "не может подключиться". Попробуйте перевести сервер в формат "ldap://xxxx", убедитесь, что userDN установлен правильно (с доменом и т. Д.).

Я часто использую WireShark, чтобы увидеть, что происходит на сетевом уровне (он знает о протоколе LDAP).

Я работаю над интеграцией Forefront Identity Manager. Поэтому код, который я пишу, всегда исходит от нескольких вызывающих клиентов. Это может не подходить, если вы пытаетесь упаковать приложение для использования "где угодно".

Я просто хотел обновить эту ветку простым решением для серверов Novell, у которых включена опция "требуется конфиденциальность" по умолчанию для TLS/SSL.

1) Убедитесь, что вы получаете SSL-сертификаты с сервера Novell, с которым вы также связываетесь, и регистрируете их в доверенном хранилище на исполняющем клиент-сервере. Обычно есть два 1 для IP и имени хоста, в зависимости от которого вы будете звонить (предпочтительно DNS)

2) Импортируйте следующие / добавьте ссылки, используя System.DirectoryServices; использование System.DirectoryServices.Protocols;

3) Вот фрагмент. Убедитесь, что вы выбрали AuthenticationTypes.SecureSocketsLayer, который является ключевым.

// serverAddress = Server IP or DNS (Match SSL certificate)
// ObjectDN = The DN of the user you are binding to
// userName = Account which will be used to make the bind
// password = password of the user which will make the bind
// value = The value you wish to add to the attribute

// Connect to the user in LDAP
DirectoryEntry entry = new DirectoryEntry("LDAP://" + serverAddress + "/" + ObjectDN + ""
                , userName
                , password
                , AuthenticationTypes.SecureSocketsLayer);
// Write the Updated attribute
entry.Properties["attribute"].Value = value;
// Read back the updated Attribute into a label
label.Text = entry.Properties["attribute"].Value.ToString();

Я думаю, что я, возможно, уже предложил этот ответ кому-то еще в другом вопросе.

[OtherQuestion по LDAP][1]

Я думаю, что есть две проблемы: 1) Какую привязку вы пытаетесь сделать? SSL? Очистить текст? Anonymous?

2) Как это настроено на стороне eDirectory для привязок LDAP?

Инструмент LDAP Browser, вы ссылаетесь на этот по этой ссылке? Бесплатный браузер LDAP

На стороне eDirectory им может потребоваться TLS для всех соединений LDAP, и они могут запретить анонимные привязки.

Можете ли вы попросить людей на другом конце включить трассировку LDAP (Использование DStrace с включенной опцией +LDAP, некоторые ссылки на то, как использовать Dstrace в Novell eDirectory, смотрите: Различные типы захвата Dstrace и понимание DS Trace для Identity Manager.)

Это обычно показывает сообщение об ошибке, которое просветит вас.

Я предполагаю, что либо Require TLS включен, и вы, возможно, не делаете успешную привязку SSL.

Если это так, попробуйте подключиться к порту 636 с включенным протоколом SSL и полностью определенным DN для пользователя, под которым вы пытаетесь войти.

Если вы пытаетесь включить SSL и у вас не появляется всплывающее окно о принятии доверенного корневого сертификата ЦС дерева, то, возможно, ЦС или сертификат SSL о том, что сервер eDirectory является пользователем, устарел или поврежден. (Есть много причин для этого, которые могут быть общими, и на это нужно лишь мгновение).

Обычно в Dstrace вы видите ошибку о сертификате SSL, если есть проблема. Пример с точки зрения Novell Identity Manager сертификата с истекшим сроком действия находится в этой статье: Сертификат истек, а также некоторые подробности о том, как исправить сертификаты.

Следующая возможность состоит в том, что указанное вами DN не совсем корректно.

Дай мне знать, если тебе еще понадобится помощь.

Я прошел через этот сценарий, для меня служба Novell LDAP, работающая в контейнере Kubernetes. Я попытался добавить сертификат CA в хранилище доверия Mono, которое добавит файл в "/usr/share/.mono/certs/Trust" в контейнере Linux. Но ничего не работало, по-прежнему подключение Novell не удалось для порта LDAP 636.

Наконец, я заставил его работать следующим образом:

LdapConnection Connection = new LdapConnection();
    Connection.SecureSocketLayer = true;
    Connection.UserDefinedServerCertValidationDelegate += new
            Novell.Directory.Ldap.RemoteCertificateValidationCallback(LdapSSLHandler);

    public bool LdapSSLHandler(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain,
                  System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == sslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (certificate.GetCertHashString() == "YOUR CERTIFICATE HASH KEY") // Thumbprint value of the certificate
        {
            return true;
        }

        return false;
    }

После моего предыдущего поста - если вам нужно использовать безопасное соединение, попробуйте использовать ldaps:// в качестве префикса к адресу сервера.

Если поддержка SSL/TLS отсутствует, вы можете попробовать это - рекомендации и оболочку.NET для библиотеки OpenLDAP.

Один важный момент - в OpenLDAP есть параметры для уровня безопасности TLS, поэтому, если у вашего сервера LDAP есть самозаверяющий сертификат, вы должны либо импортировать его на стороне клиента, либо настроить TLS, чтобы не проверять права подписи *, что, конечно, менее безопасно.).

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