Как аутентифицировать LDAP в .NET

Я хотел бы аутентифицировать имя пользователя и пароли для своего приложения в операционной системе Windows с любой службой каталогов. Например, это может быть Microsoft Active Directory, Novell eDirecotry или SunOne. Я уже знаю, как сделать этот код изначально для Microsoft Active Direcotry с помощью C #. (Я полностью отказался от использования ADSI и создания низкоуровневого компонента com)

Я пытаюсь пройти аутентификацию с помощью Novel eDirecotory, я установил проект Mono. Внутри монопроекта они предоставляют Novell.Directory.ldap.dll. Код выглядит примерно так же, как и для Microsoft Active Directory. (http://www.novell.com/coolsolutions/feature/11204.html)

Для SunOne мне сказали использовать тот же код, что и для активного руководства, но строка подключения ldap немного отличается. (http://forums.asp.net/t/354314.aspx) (http://technet.microsoft.com/en-us/library/cc720649.aspx)

Чтобы усложнить мой проект, большинство клиентов используют «Учетную запись службы:», что означает, что мне нужно выполнить привязку с административным именем пользователя и паролем, прежде чем я смогу аутентифицировать обычное имя пользователя и пароль. Мои вопросы состоят из 2 частей.

1) Исходя из того, что я объяснил выше, является ли это правильным направлением, которое я должен собираться аутентифицировать для каждой отдельной службы директивы?

2) Я чувствую, что мне вообще не нужно делать ничего из этого кода. Я также считаю, что условие использования учетной записи службы совершенно не важно. Если все, что меня волнует, - это аутентификация имени пользователя и пароля на машине с Windows, зачем мне вообще использовать ldap? Я имею в виду, подумайте об этом. Когда вы входите в систему утром, вам не нужно предоставлять учетную запись службы только для входа в систему. Я могу легко аутентифицировать имя пользователя и пароль в приглашении DOS, используя функцию runas, и мне будет отказано или нет, и я смогу проанализировать текстовый файл. Я уверен, что есть другие способы передать имя пользователя и пароль операционной системе Windows, в которой я работаю, и сообщать мне, действительны ли имя пользователя и пароль для домена, в котором он находится. Я прав? Если да, то какие у вас есть предложения?

Майкл Эванчик www.MikeEvanchik.com


person Michael Rudner Evanchik    schedule 20.04.2009    source источник


Ответы (3)


Все это можно сделать с помощью System.DirectoryServices.Protocols. Если вы создаете LdapConnection для каталога, вы можете использовать учетную запись службы для привязки, а затем выполнить последующую привязку для проверки подлинности учетных данных.

Учетная запись службы обычно используется для ограничения доступа к механизму аутентификации сервера. Таким образом, ни один случайный человек на улице не сможет попытаться авторизоваться на вашем сервере LDAP.

Кроме того, ожидаете ли вы, что каждый пользователь будет указывать свое отличительное имя при входе в систему? В Active Directory требуется только sAMAccountName, но другие поставщики, такие как eDirectory и SunONE, требуют отличительное имя для аутентификации.

Чтобы выполнить этот тип аутентификации, вам нужно будет использовать учетную запись службы, которая предоставляется для аутентификации на сервере, выполнить поиск пользователя с данным именем пользователя и получить это отличительное имя пользователя. Затем вы можете пройти аутентификацию, используя это отличительное имя и предоставленный пароль.

Это будет работать для всех систем LDAP, за исключением Active Directory, которая будет довольна только sAMAccountName.

person Jared    schedule 07.05.2009

Я не уверен, что полностью понимаю вопрос, но в некоторых ситуациях мне было легко аутентифицировать пользователя, просто выполнив поиск его учетной записи и используя его учетные данные в качестве имени пользователя и пароля.

Успешный запрос означает, что все предоставлено правильно, отсутствие учетной записи означает, что что-то не так.

//use the users credentials for the query
DirectoryEntry root = new DirectoryEntry(
    "LDAP://dc=domain,dc=com", 
    loginUser, 
    loginPassword
    );

//query for the username provided
DirectorySearcher searcher = new DirectorySearcher(
    root, 
    "(sAMAccountName=" + loginUser + ")"
    );    

//a success means the password was right
bool success = false; 
try {
    searcher.FindOne();
    success = true;
}
catch {
    success = false;
}

Вероятно, это не лучшая практика, но вы можете обойти вашу проблему ...

person hugoware    schedule 20.04.2009
comment
Я предполагаю, что это только Microsoft AD и LDAP. Спасибо за код. Мой вопрос - это скорее способ универсального использования, возможно, без использования LDAP, поскольку некоторые серверы LDAP требуют имени пользователя и пароля учетной записи службы, просто для привязки, поэтому вы даже можете попытаться аутентифицировать обычного пользователя. - person Michael Rudner Evanchik; 21.04.2009
comment
Это то, что я предлагаю - использовать учетные данные вошедшего в систему пользователя (при условии, что вы запрашиваете его имя пользователя и пароль) в качестве учетной записи службы. По крайней мере, они должны иметь возможность запрашивать и видеть свою учетную запись. Если это сработает, значит, аутентификация работает. Это кажется довольно универсальным способом проверить правильность пароля. - person hugoware; 21.04.2009

У нас был веб-сайт, на котором необходимо было аутентифицировать имя пользователя и пароль по учетным данным домена, и мы использовали функцию API LogonUser. Используйте его для входа в сеть (один из его аргументов - тип входа в систему), и все, что он делает, это проверяет учетные данные, он не делает таких вещей, как загрузка профиля пользователя, как это сделал бы runas. Единственное предостережение - учетная запись службы требует достаточного доступа для вызова LogonUser. Я предлагаю вам проверить документацию MSDN, что это за доступ, потому что он зависит от ОС.

person pipTheGeek    schedule 20.04.2009
comment
спасибо, что направили меня по правильному пути. хотя ваше право, вам понадобится локальный администратор, чтобы сделать этот вызов api, что-то погуглить, если вы читаете эту ветку, они говорят, что есть вызов api, который не требует этого vbforums.com/showthread.php?t=240277 AcquireCredentialsHandleNT с находится в security.dll - person Michael Rudner Evanchik; 21.04.2009
comment
Если вы используете 2003, то LogonUser не требует SE_TCB_NAME. Я не думаю, что простой вызов AcquireCredentialsHandle проверит их действительность. Код имитирует полную проверку аутентификации клиент / сервер. Но не вижу в этом ничего плохого, кроме очевидного количества кода. - person pipTheGeek; 21.04.2009