I don't know how to search for users in Active Directory. This is my current attempt, but I have not run it yet.
public class ADController : Controller
{
[HttpGet]
public IActionResult Find()
{
return View();
}
[HttpPost]
public IActionResult Find(FindViewModel model)
{
DirectoryEntry entry = new DirectoryEntry("LDAP://<full user name>,<Users>,<domain component>");
DirectorySearcher searcher;
SearchResultCollection results;
searcher = new DirectorySearcher(entry);
searcher.Filter = "(&(objectClass=user)(displayname=*))";
searcher.SearchScope = SearchScope.Subtree;
using (searcher)
{
results = searcher.FindAll();
foreach (SearchResult result in results)
{
string searchOK = result.Properties["displayname"][0].ToString();
//objects.Add(searchOK);
}
}
return View();
}
}
public class FindViewModel
{
[Display(Name = "UserActiveDirectory")]
public string UserAD { get; set; }
}
Your requirements are a bit unclear, but I am assuming that:
displayName
of the found user to your viewIf that's the case, then:
First, since you only need to pass a single string into your controller, there's no benefit to using a class as the parameter. Just use a single string:
public IActionResult Find(string username)
Then you need to use the username in your filter. There is no attribute called "username", but that most often refers to the sAMAccountName
. However it could also refer to the userPrincipalName
, which has the format of username@example.com
. But I'll assume sAMAccountName
.
Just (objectClass=user)
is oddly not enough to limit the search to just user accounts. Computer objects, for example, have an objectClass
of user
. So if you want to limit the search to only user accounts, you need to also include (objectCategory=person)
.
searcher.Filter = $"(&(objectClass=user)(objectCategory=person)(sAMAccountName={username}))";
The SearchScope
is Subtree
by default, so you don't need this line:
searcher.SearchScope = SearchScope.Subtree;
You should also use the PropertiesToLoad
collection because, if you don't, it will return every attribute. So put only the attributes you plan on using there:
searcher.PropertiesToLoad.Add("displayName");
Since you're searching by sAMAccountName
, which is guaranteed to be unique on the domain, you can use FindOne()
instead of FindAll()
, since you know there can only be one result (or none).
var result = searcher.FindOne();
If result
is not null
, that means the user was found and you can pass the displayName
to the view:
if (result != null) {
string displayName = (string) result.Properties["displayname"][0];
return View(displayName);
}
Otherwise, don't pass anything to the view, and you will have to handle that case in the view.
Altogether, that looks like this:
public IActionResult Find(string username)
{
var entry = new DirectoryEntry("LDAP://<full user name>,<Users>,<domain component>");
var searcher = new DirectorySearcher(entry) {
Filter = $"(&(objectClass=user)(objectCategory=person)(sAMAccountName={username}))",
PropertiesToLoad = { "displayName" }
};
var result = searcher.FindOne();
if (result != null) {
string displayName = (string) result.Properties["displayname"][0];
return View(displayName);
}
return View();
}
You may still have to make some updates depending on your actual requirements, but this should get you started.