Использование С# для аутентификации пользователя с помощью LDAP
Я использую DirectorySearcher для поиска пользовательской записи на сервере LDAP.
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://myserver/OU=People,O=mycompany";
de.AuthenticationType = AuthenticationTypes.None;
DirectorySearcher deSearch = new DirectorySearcher();
deSearch.SearchRoot = de;
deSearch.Filter = "(uid=" + model.UserName + ")";
SearchResult result = deSearch.FindOne();
Я могу получить требуемый вывод в переменной результата.
Однако, если я пытаюсь выполнить аутентификацию одного и того же пользователя, указав пароль в записи каталога, я всегда получаю следующую ошибку.
"Имя пользователя или пароль неверны".
DirectoryEntry entry = new DirectoryEntry("LDAP://myserver/OU=People,O=mycompany", username, password);
DirectorySearcher search = new DirectorySearcher(
entry,
"(uid=" + username + ")",
new string[] { "uid" }
);
search.SearchScope = System.DirectoryServices.SearchScope.Subtree;
SearchResult found = search.FindOne(); ->>>>>this is where I get wrong credential error.
Имя пользователя и пароль для пользователя, которого я хочу проверить.
Может кто-нибудь сказать мне, что я делаю неправильно здесь или как отлаживать это.
Ответы
Ответ 1
Это имя пользователя и пароль в этой строке:
DirectoryEntry("LDAP://myserver/OU=People,O=mycompany", username, password);
должен быть для учетной записи, которая имеет разрешение на поиск каталога. Это может быть служебная учетная запись или цель тестирования с вашим собственным. Это не должно быть пользователем/проходом того, кого вы пытаетесь аутентифицировать.
Если вы хотите выполнить аутентификацию, вы можете использовать следующие шаги, используя PrincipalContext:
using(var context = new PrincipalContext(ContextType.Domain, "mydomain", "mydomain\serviceAcct", "serviceAcctPass")) {
//Username and password for authentication.
return context.ValidateCredentials(username, password);
}
"serviceAcct" = учетная запись пользователя домена, у которой есть разрешение на поиск каталога.
"serviceAcctPass" = пароль для этой учетной записи службы.
Как я уже сказал, для тестирования вы можете попробовать свой собственный контекст пользователя/пароля.
Кроме того, убедитесь, что предоставленное имя пользователя имеет либо форматирование домена "имя пользователя", либо "имя пользователя @домена".
Ответ 2
Здесь мы получаем данные о пользователях активного каталога и можем использовать имя домена и имя пользователя из файла web.config
bool isAdmin = false;
RegisterInput model = new RegisterInput();
NewUserInput usr = new NewUserInput();
SearchResultCollection results;
string mobileNumber = string.Empty;
using (DirectoryEntry domainEntry = new DirectoryEntry("LDAP://" + AppSettings.DomainName))
{
using (DirectorySearcher searcher = new DirectorySearcher(domainEntry, "userPrincipalName=" + userName + "@" + AppSettings.DomainName) { Filter = string.Format("(&(objectClass=user)(samaccountname={0}))", userName) })
{
results = searcher.FindAll();
if (results.Count > 0)
{
usr.FirstName = results[0].GetDirectoryEntry().Properties["givenName"].Value.ToString();
usr.LastName = results[0].GetDirectoryEntry().Properties["sn"].Value?.ToString();
usr.EmailAddress = results[0].GetDirectoryEntry().Properties["mail"].Value?.ToString();
mobileNumber = results[0].GetDirectoryEntry().Properties["mobile"]?.Value?.ToString();
dynamic userRoleList = results[0].GetDirectoryEntry().Properties["memberOf"];
if (userRoleList != null)
{
foreach (var role in userRoleList)
{
string[] split = role.ToString().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
bool result = split.Any(x => x.ToLowerInvariant() == AppSettings.UserRole.ToLowerInvariant());
if (result)
{
isAdmin = true;
break;
}
}
}
}
}
}
model.NewUser = usr;