Wednesday, November 10, 2010

Working with Active Directory using C#

I am writing this post to all of you looking for the sample to work with Active directory services with various operations using C#. In this article, I would like to explain the below operations with Active Directory.

Operations:



  1. Create User
  2. Create Group
  3. Add User to Group
  4. Create user and add to Group
  5. Disable User
  6. Enable User
  7. Remove User from Group
  8. Remove Group
  9. Remove User


Sample Code:

using System;
using System.DirectoryServices.AccountManagement;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace Aryabhatt.Samples.ActiveDirectory
{
    internal class AccountManagementService
    {
        // AD Domain Name for connecting through LDAP
        static string adDomain = ConfigurationManager.AppSettings["DomainName"];
        // User information like (OU)
        static string adContainer = ConfigurationManager.AppSettings[Constants.ConfigKeys.AD_CONTAINER];
        // Group information like (OU)
        static string adGroupContainer = ConfigurationManager.AppSettings[Constants.ConfigKeys.AD_GROUP_CONTAINER];

        // Service user name
        static string adminUser = ConfigurationManager.AppSettings[Constants.ConfigKeys.AD_SERVICE_USERNAME];
        // Service password
        static string adminPassword = ConfigurationManager.AppSettings[Constants.ConfigKeys.AD_SERVICE_PASSWORD];

        // AD LDS or AD user context
        static PrincipalContext adPrincipalContext = new PrincipalContext(
                                                                          ContextType.Domain,
                                                                          adDomain,
                                                                          adContainer,
                                                                          ContextOptions.Negotiate | ContextOptions.Sealing | ContextOptions.Signing,
                                                                          adminUser,
                                                                          adminPassword);

        /// <summary>
        /// Authenticates the user with the credentials against Active Directory
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="password">Password</param>
        public static void ValidateUserCredentials(string userName, string password)
        {
            PrincipalContext principalContext =
                new PrincipalContext(
                    ContextType.ApplicationDirectory,
                    adDomain,
                    adContainer);
            return principalContext.ValidateCredentials(userName, password);
        }

        /// <summary>
        /// Checks if the provided userName already exists in the Active Directory. Returns True if exists.
        /// </summary>
        /// <param name="userName">User Name</param>
        /// <returns>Returns true if the user exists in AD otherwise false</returns>
        internal static bool IsUserExist(string userName)
        {
            bool userExists = true;

            try
            {
                using (UserPrincipal user = new UserPrincipal(adPrincipalContext))
                {
                    user.Name = userName;

                    // create a principal searcher for running a search operation
                    using (PrincipalSearcher principalSearcher = new PrincipalSearcher())
                    {
                        // assign the query filter property for the principal object
                        principalSearcher.QueryFilter = user;
                        // run the query
                        using (Principal result = principalSearcher.FindOne())
                        {
                            if (result == null)
                            {
                                userExists = false;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY);
                // Not rethrowing here as AppException being thrown on the caller
            }
            return userExists;

        }

        /// <summary>
        /// Returns UserProfile object for the passed userName
        /// </summary>
        /// <param name="userName">userName</param>
        /// <returns></returns>
        private static UserPrincipal GetUserPrincipal(string userName)
        {
            UserPrincipal user = new UserPrincipal(adPrincipalContext);
            user.Name = userName;
            UserPrincipal userPrincipalResult;
            using (PrincipalSearcher principalSearcher = new PrincipalSearcher(user))
            {
                userPrincipalResult = (UserPrincipal)principalSearcher.FindOne();
            }
            user.Dispose();
            return userPrincipalResult;
        }

        /// <summary>
        /// Returns GroupPrincipal object based on the groupName passed
        /// </summary>
        /// <param name="groupName">Group Name</param>
        /// <param name="adGroupContainer">AD Group container</param>
        /// <returns></returns>
        private static GroupPrincipal GetGroupPrincipal(string groupName, string adGroupContainer)
        {
            GroupPrincipal groupPrincipalResult;


            // AD LDS or AD group context
            PrincipalContext adGroupPrincipalContext = new PrincipalContext(
                                                              ContextType.Domain,
                                                              adDomain,
                                                              adGroupContainer,
                                                              ContextOptions.Negotiate | ContextOptions.Sealing | ContextOptions.Signing,
                                                              adminUser,
                                                              adminPassword);

            GroupPrincipal group = new GroupPrincipal(adGroupPrincipalContext);
            using (group)
            {
                group.Name = groupName;

                using (PrincipalSearcher principalSearcher = new PrincipalSearcher(group))
                {
                    groupPrincipalResult = (GroupPrincipal)principalSearcher.FindOne();
                }
            }
            return groupPrincipalResult;
        }

        /// <summary>
        /// Creates an active directory user account
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="password">Password</param>
        /// <param name="firstName">First name</param>
        /// <param name="lastName">Last name</param>
        /// <param name="emailAddress">Email address</param>
        public static void CreateUser(string userName, string password, string firstName, string lastName, string emailAddress)
        {
            if (IsUserExist(userName))
                throw new ApplicationException(Constants.ExceptionMessages.USER_EXISTS);

            try
            {
                // create a user principal, set their password and enable the account
                using (UserPrincipal user = new UserPrincipal(adPrincipalContext, userName, password, true))
                {
                    // assign some properties to the user principal
                    user.GivenName = firstName;
                    user.Surname = lastName;
                    user.EmailAddress = emailAddress;
                    if (!userName.Contains("@"))
                        user.UserPrincipalName = string.Format("{0}@{1}", userName, adDomain); // Setting up UPN value

                    user.Save();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Deletes the user from AD Domain
        /// </summary>
        /// <param name="userName"></param>
        public static void RemoveUser(string userName)
        {
            try
            {
                using (UserPrincipal user = GetUserPrincipal(userName))
                {
                    user.Delete();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Adds user to a Group
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="groupName">Group name</param>
        public static void AddUserToGroup(string userName, string groupName, string adGroupContainer)
        {
            try
            {
                using (UserPrincipal user = GetUserPrincipal(userName))
                {
                    using (GroupPrincipal group = GetGroupPrincipal(groupName, adGroupContainer))
                    {
                        group.Members.Add(user);
                        group.Save();
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Adds user to a Group
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="groupName">Group name</param>
        public static void CreateUserAndAddToGroup(string userName, string password, string firstName, string lastName, string emailAddress, string groupName, string adGroupContainer)
        {
            if (IsUserExist(userName))
                throw new ApplicationException(Constants.ExceptionMessages.USER_EXISTS);

            try
            {
                // create a user principal, set their password and enable the account

                UserPrincipal user = new UserPrincipal(adPrincipalContext, userName, password, true);
                using (user)
                {
                    // assign some properties to the user principal
                    user.GivenName = firstName;
                    user.Surname = lastName;
                    user.EmailAddress = emailAddress;
                    if (!userName.Contains("@"))
                        user.UserPrincipalName = string.Format("{0}@{1}", userName, adDomain); // Setting up UPN value
                    user.Save();

                    GroupPrincipal group = GetGroupPrincipal(groupName, adGroupContainer);// GroupPrincipal.FindByIdentity(adGroupPrincipalContext, groupName);
                    using (group)
                    {
                        group.Members.Add(user);
                        group.Save();
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Removes user from a group
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="groupName">Group name</param>
        public static void RemoveUserFromGroup(string userName, string groupName, string adGroupContainer)
        {
            try
            {
                using (UserPrincipal user = GetUserPrincipal(userName))
                {
                    using (GroupPrincipal group = GetGroupPrincipal(groupName, adGroupContainer))
                    {
                        bool isDeleted = group.Members.Remove(user);
                        group.Save();
                    }
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Activates the user
        /// </summary>
        /// <param name="userName">User name</param>
        public static void ActivateUser(string userName)
        {
            try
            {
                using(UserPrincipal user = GetUserPrincipal(userName))
                {
                    user.Enabled = true;
                    user.Save();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Disables the user from Domain
        /// </summary>
        /// <param name="userName">User name</param>
        public static void DisableUser(string userName)
        {
            try
            {
                using (UserPrincipal user = GetUserPrincipal(userName))
                {
                    user.Enabled = false;
                    user.Save();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Creates the group in AD
        /// </summary>
        /// <param name="groupName"></param>
        public static void CreateGroup(string groupName)
        {
            try
            {
                // create a group
                GroupPrincipal group = new GroupPrincipal(adGroupPrincipalContext, groupName);
                using (group)
                {
                    group.Save();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }

        /// <summary>
        /// Removes the group from AD
        /// </summary>
        /// <param name="groupName"></param>
        public static void RemoveGroup(string groupName, string adGroupContainer)
        {
            try
            {
                // fetching a group
                using (GroupPrincipal group = GetGroupPrincipal(groupName, adGroupContainer))
                {
                    group.Delete();
                }
            }
            catch (Exception ex)
            {
                if (ExceptionPolicy.HandleException(ex, Constants.Policies.SERVICE_BOUNDARY))
                    throw ex;
            }
        }
    }
}

Web.Config Entries:

<add key="DomainName" value="Dev.Arybhatt.com" />


<add key="UserName" value="ServiceAdmin" />


<add key="Password" value="P@ssw0rd1" />


<add key="UserContainer" value="OU=DevUsers,DC=Dev,DC=Arybhatt,DC=com" />


<add key="GroupContainer" value="OU=Demo,OU=Apps,DC=Dev,DC=Arybhatt,DC=com" />



Organizational Unit: An organizational unit (OU) is a subdivision within an Active Directory into which you can place users, groups, computers, and other organizational units. You can create organizational units to mirror your organization's functional or business structure. Each domain can implement its own organizational unit hierarchy. If your organization contains several domains, you can create organizational unit structures in each domain that are independent of the structures in the other domains.


User Principal : User principal object can contain only the users in the OU.
Group Principal: Group principal object can contain only the groups in the OU.
Domain Name: Domain name


Hope you got to know how simple it is. :)


Regards
Gangadhar Kotu