views:

525

answers:

3

I need to access Active Directory to get information about groups that customers belong to. The project I have is an ASP.Net MVC application using C#. I've never programmed against Active Directory before, and need some advice on what the best way to get started is, what security model to use to access the information, and maybe point me to some good tutorials.

+3  A: 

Use System.DirectoryServices namespace to access the AD.

The two most important classes are:

  1. DirectoryEntry;
  2. DirectorySearcher.

Let's suppose that your domain is: MyIntranet.MyCompany.com

Then, you will have to create a root instance of the DirectoryEntry class:

DirectoryEntry root = new DirectoryEntry("LDAP://DC=MyIntranet,DC=MyCompany,DC=com");

When searching the AD for a particular occurence of a group or user:

DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;

Let's say you want to look for a username named: AnyUser1, the DirectorySearcher.Filter should look like:

searcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(sAMAccountName={0})", "AnyUser1");

Then, get the result through the SearchResult class as follows:

bool userFound = false;
SearchResult foundUser = null;

try {
    foundUser = searcher.FindOne(); // You might as well use the FindAll() method if you expect more then one result.
    userFound = foundUser != null;
} catch(Exception) {
    throw;
}

if (!userFound)
    return;

DirectoryEntry user = foundUser.GetDirectoryEntry();

Then, you may get the groups which this user is member of like so through the memberOf property:

user.Properties("memberOf").Value

For a good overview, see this CodeProject article: How to (almost) everything in Active Directory.

And ofr a list of the properties: Mapping Between IADsUser Properties and Active Directory Attributes.

EDIT #1

If you're using impersonation, you might perhaps consider setting some parameters to your application such as DefaultRootDomain, DefaultUserName and DefaultPassword, then use them when instantiating your root DirectoroEntry.

public static class AdHelper {

    public static string DefaultRootDse {
        get {
            return Properties.Settings.Default.DefaultRootDomain;
        }
    }

    private static string DefaultUserName {
        get {
            return Properties.Settings.Default.DefaultUserName;
        }
    }

    private static string DefaultPassword {
        get {
            return Properties.Settings.Default.DefaultPassword;
        }
    } 

    public static DirectoryEntry RootDse {
        get {
            if (_rootDse == null)
                _rootDse = new DirectoryEntry(DefaultRootDse, DefaultUserName, DefaultPassword);
            return _rootDse;
        }
    }
    private static DirectoryEntry _rootDse;
}
Will Marcouiller
Don't I need to specifiy a user account and password to use to access the data?
Russ Clark
If you use impersonation, yes. Otherwise, the `DirectoryEntry` class and the AD assumes the currently connected user (for a Windows session, let's say. I don't know about using it through a Web application).
Will Marcouiller
+8  A: 

Since you're using MVC, you have access to the new System.DirectoryServices.AccountManagement namespace in .NET 3.5. These classes should be preferred over the older classes in DirectoryServices itself as they are much simpler to use. There are a couple of gotchas that haven't been solved in 3.5 (1500 member limit when querying groups, for instance), but I'm assured that these have been fixed in .NET 4.0. For most tasks, the new classes work very well.

 using (var context = new PrincipalContext( ContextType.Domain )) 
 {
      using (var user = UserPrincipal.FindByIdentity( context, "username" ))
      {
          var groups = user.GetAuthorizationGroups();
          ...
      }
 }
tvanfosson
+1 Interesting! I have only had the chance to work against the AD in .NET 2.0. =)
Will Marcouiller
Really, really sexy!
Dänu
A: 

If you have .NET 3.5 or if you can upgrade to it - by all means use the new feature in System.DirectoryServices.AccountManagement!

See a great intro article Managing Directory Security Principals in the .NET Framework 3.5 on MSDN Magazine for more information and a jumpstart.

marc_s