Аутентификация LDAP в .NET
Я хотел бы аутентифицировать имя пользователя и пароли для моего приложения в операционной системе Windows с любой службой каталогов. Например, это может быть активный каталог microsoft, Novell eDirecotry или SunOne. Я уже знаю, как сделать этот код изначально для Microsoft Active Direcotry с С#. (Я полностью отказался от использования ADSI и создал компромисс с низким уровнем)
Как я пытаюсь выполнить аутентификацию с помощью 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
Ответы
Ответ 1
Все это можно сделать с помощью System.DirectoryServices.Protocols. Если вы создаете LdapConnection в каталоге, вы можете использовать учетную запись службы для связывания с ней, а затем сделать последующую привязку для аутентификации учетных данных.
Учетная запись службы обычно используется для ограничения доступа к механизму аутентификации сервера. Таким образом, ни один случайный человек на улице не может попытаться выполнить авторизацию с вашим сервером LDAP.
Кроме того, вы ожидаете, что каждый пользователь будет предоставлять свое выдающееся имя при входе в систему? В Active Directory требуется только имя sAMAccountName, но для других поставщиков, таких как eDirectory и SunONE, требуется различное имя для аутентификации.
Чтобы выполнить этот тип аутентификации, вам нужно будет использовать учетную запись службы, которая предоставляется для аутентификации на сервере, выполнить поиск пользователя с заданным именем пользователя и захватить это имя пользователя. Затем вы можете выполнить аутентификацию с использованием этого различающегося имени и пароля, который был предоставлен.
Это будет работать для всех LDAP-систем, за исключением Active Directory, которые будут довольны только именем sAMAccountName.
Ответ 2
Я не уверен, что полностью понимаю вопрос, но в некоторых ситуациях мне было легко аутентифицировать пользователя, просто выполнив поиск их учетной записи и используя свои учетные данные в качестве имени пользователя и пароля.
Успешный запрос означает, что все предоставленное было правильным, не обнаружив, что учетная запись означает, что что-то не так.
//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;
}
Наверное, не "лучшая практика", но может обойти вашу проблему, которую вы имеете...
Ответ 3
У нас был веб-сайт, который должен был аутентифицировать имя пользователя и пароль для учетных данных домена и использовать функцию LogonUser API. Используйте его для сетевого входа (один из его аргументов - тип входа), и все, что он делает, проверяет учетные данные, он не выполняет такие действия, как загрузка профиля пользователя, который был бы runas.
Только оговорка заключается в том, что учетная запись службы требует достаточного доступа к вызову LogonUser. Я предлагаю вам проверить документацию MSDN на наличие этого доступа, поскольку он зависит от ОС.