Reputation: 1665
The below code works on my local machine by returning the user's full name from Active Directory:
string principal = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name.Remove(0, 12);
string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", principal);
string[] properties = new string[] { "fullname" };
DirectoryEntry adRoot = new DirectoryEntry("LDAP://myserver.com");
adRoot.AuthenticationType = AuthenticationTypes.Secure;
DirectorySearcher searcher = new DirectorySearcher(adRoot);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.PropertiesToLoad.AddRange(properties);
searcher.Filter = filter;
SearchResult result = searcher.FindOne();
DirectoryEntry directoryEntry = result.GetDirectoryEntry();
string displayName = directoryEntry.Properties["displayName"][0].ToString();
if (string.IsNullOrEmpty(displayName) == false)
{
return displayName;
}
When I publish it to the development server I get the following error:
System.NullReferenceException: Object reference not set to an instance of an object.
The error is thrown on the following line:
DirectoryEntry directoryEntry = result.GetDirectoryEntry();
I have tried
DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domain, AdAdminUsername, AdAdminPassword, AuthenticationTypes.Secure);
but still no joy.
Any ideas?
Thanks!
Upvotes: 2
Views: 6063
Reputation: 72680
Just from outside : your string called principal
is built by the following :
string principal = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name.Remove(0, 12);
Have you log 'System.Web.HttpContext.Current.Request.LogonUserIdentity.Name
' on your dev server ? This static construction may be the begining of you troubles because if principal
is'nt what you think it is, the result of FindOne may be NULL.
Upvotes: 1
Reputation: 755371
In your current code, you must check for NULL
after the call to FindOne()
- it could return a NULL
value if no matching directory entry was found.
If more than one entry is found during the search, only the first entry is returned. If no entries are found to match the search criteria, a null reference (Nothing in Visual Basic) is returned.
Plus, you should also always check for the presence of a property before accessing it - it could be absent.....
Therefore, your code should be something like this:
SearchResult result = searcher.FindOne();
if(result != null)
{
DirectoryEntry directoryEntry = result.GetDirectoryEntry();
if(directoryEntry.Properties["displayName"] != null &&
directoryEntry.Properties["displayName"].Length > 0)
{
string displayName = directoryEntry.Properties["displayName"][0].ToString();
if (!string.IsNullOrEmpty(displayName))
{
return displayName;
}
}
}
But: if you're on .NET 3.5 or newer, you should check out the System.DirectoryServices.AccountManagement
namespace which makes a lot of things a lot easier when dealing with Active Directory.
You can use a PrincipalSearcher
and a "query-by-example" principal to do your searching:
// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// define a "query-by-example" principal - here, we search for a UserPrincipal
// and with the first name (GivenName) of "Bruce"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.SamAccountName = "whatever you're looking for.....";
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement
Of course, depending on your need, you might want to specify other properties on that "query-by-example" user principal you create:
Surname
(or last name)DisplayName
(typically: first name + space + last name)SAM Account Name
- your Windows/AD account nameUser Principal Name
- your "username@yourcompany.com" style nameYou can specify any of the properties on the UserPrincipal
and use those as "query-by-example" for your PrincipalSearcher
.
Upvotes: 2