"If at first you don't succeed; call it version 1.0" :-Unknown

Pages

Monday, July 15, 2013

Accessing active directory using c#

Hi *.*,
Today i'm sharing a snippet to Accessing active directory using c#. i had created a class file for modular access.Here it goes



using System;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices;
using System.Configuration;
using System.Collections.Generic;


namespace ActiveDirectoryComm.Support
{
    public class ActiveDirectoryHelper
    {
        #region Private Fields
        private PrincipalContext principalContext;
        private string newUserDefaultPassword = string.Empty;
        private UserPrincipal userPrincipal;
        #endregion

        #region INIT
        private ActiveDirectoryHelper()
        {
            Initialize();
        }
        #endregion

        #region Public Methods
        /// <summary>
        ///
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public PasswordChangeStatus SetPassword(string username, string password)
        {
            using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, username))
            {
                if (userPrincipal == null)
                    return PasswordChangeStatus.InvalidUser;

                try
                {
                    userPrincipal.SetPassword(password);
                    userPrincipal.Save();
                    return PasswordChangeStatus.Changed;
                }
                catch (PasswordException ex)
                {
                    return PasswordChangeStatus.InvalidPassword;
                }
                catch
                {
                    if (principalContext == null)
                        return PasswordChangeStatus.ServerUnreachable;

                    return PasswordChangeStatus.FailedOtherReason;
                }
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userStatus"></param>
        /// <returns></returns>
        public UserAccountOperationStatus SetUserAccountStatus(string userName, UserAccountStatus userStatus)
        {
            if (string.IsNullOrEmpty(userName))
                return UserAccountOperationStatus.InvalidUser;

            if (principalContext == null)
                return UserAccountOperationStatus.ServerUnreachable;

            using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, userName))
            {
                try
                {
                    if (userPrincipal == null)
                        return UserAccountOperationStatus.InvalidUser;

                    bool isUserCurrentlyEnabled = (userPrincipal.Enabled == true);
                    bool changeNeeded = false;

                    if ((isUserCurrentlyEnabled && userStatus == UserAccountStatus.Disable) || (!isUserCurrentlyEnabled && userStatus == UserAccountStatus.Enable))
                        changeNeeded = true;

                    if (changeNeeded)
                    {
                        userPrincipal.Enabled = (userStatus == UserAccountStatus.Enable);
                        userPrincipal.Save();
                    }
                    return UserAccountOperationStatus.Success;
                }
                catch
                {
                    return UserAccountOperationStatus.FailedOtherReason;
                }
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public UserAccountOperationStatus RemoveUser(string userName)
        {
            try
            {
                using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, userName))
                {
                    if (userPrincipal == null)
                        return UserAccountOperationStatus.InvalidUser;

                    userPrincipal.Delete();
                }

                return UserAccountOperationStatus.Success;
            }
            catch
            {
                if (principalContext == null)
                    return UserAccountOperationStatus.ServerUnreachable;

                return UserAccountOperationStatus.FailedOtherReason;
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPassword"></param>
        /// <returns></returns>
        public UserCreateStatus CreateUser(string firstName, string lastName, string userLogonName, string password, string displayName, string emailAddress, string description)
        {
            try
            {
                UserPrincipal usr = UserPrincipal.FindByIdentity(principalContext, userLogonName);
                if (usr != null)
                    return UserCreateStatus.AlreadyExists;

                UserPrincipal userPrincipal = new UserPrincipal(principalContext);

                if (!string.IsNullOrEmpty(firstName))
                    userPrincipal.GivenName = firstName;

                if (!string.IsNullOrEmpty(lastName))
                    userPrincipal.Surname = lastName;

                if (!string.IsNullOrEmpty(userLogonName))
                    userPrincipal.SamAccountName = userLogonName;

                if (!string.IsNullOrEmpty(displayName))
                    userPrincipal.DisplayName = displayName;

                if (!string.IsNullOrEmpty(emailAddress))
                    userPrincipal.EmailAddress = emailAddress;

                if (!string.IsNullOrEmpty(description))
                    userPrincipal.Description = description;

                if (!string.IsNullOrEmpty(password))
                    userPrincipal.SetPassword(password);
                else
                    userPrincipal.SetPassword(newUserDefaultPassword);

                userPrincipal.Enabled = true;
                userPrincipal.ExpirePasswordNow();

                try
                {
                    userPrincipal.Save();
                }
                catch (PasswordException ex)
                {
                    return UserCreateStatus.PasswordPolicyViolated;
                }
                catch (Exception ex)
                {
                    if (principalContext == null)
                        return UserCreateStatus.ServerUnreachable;

                    return UserCreateStatus.FailedOtherReason;
                }

                /***************************************************************
                 *   The below code demonstrates on how you can make a smooth
                 *   transition to DirectoryEntry from AccountManagement namespace,
                 *   for advanced operations.
                 ***************************************************************/
                //if (userPrincipal.GetUnderlyingObjectType() == typeof(DirectoryEntry))
                //{
                //    DirectoryEntry entry = (DirectoryEntry)userPrincipal.GetUnderlyingObject();
                //    if (address != null && address.Length > 0)
                //        entry.Properties["streetAddress"].Value = address;
                //    try
                //    {
                //        entry.CommitChanges();
                //        return UserCreateStatus.Created;
                //    }
                //    catch (Exception e)
                //    {
                //        return UserCreateStatus.Failed;
                //    }
                //}

                return UserCreateStatus.Created;
            }
            catch
            {
                if (principalContext == null)
                    return UserCreateStatus.ServerUnreachable;

                return UserCreateStatus.FailedOtherReason;
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public AuthenticationStatus AuthenticateUser(string userName, string password)
        {
            try
            {
                UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, userName);
                if (userPrincipal == null)
                    return AuthenticationStatus.InvalidUser;
                else
                {

                    try
                    {
                        DirectoryEntry dirEntry = userPrincipal.GetUnderlyingObject() as DirectoryEntry;
                        object nativeObject = dirEntry.NativeObject;
                    }
                    catch (DirectoryServicesCOMException ex)
                    {

                    }
                    catch (Exception ex)
                    {

                    }
                }

                bool authSucceeded = principalContext.ValidateCredentials(userName, password);

                if (authSucceeded)
                    return AuthenticationStatus.Success;
                //If password is not accepted, check for reason

                if (userPrincipal.IsAccountLockedOut())
                    return AuthenticationStatus.AccountLockedOut;

                // BEGIN CHECK IF PASSWORD SHOULD BE CHANGED ON FIRST LOGIN
                if (PasswordRequiresToBeChanged(userPrincipal))
                    return AuthenticationStatus.PasswordNeedsToBeChanged; ;

                if (userPrincipal.LastPasswordSet == null)
                    return AuthenticationStatus.PasswordNeedsToBeChanged;

                //////var deUser = userPrincipal.GetUnderlyingObject() as DirectoryEntry;
                //////var property = deUser.Properties["pwdLastSet"];
                //////property.Value = -1;
                //////deUser.CommitChanges();

                // BEGIN CHECK IF PASSWORD SHOULD BE CHANGED ON FIRST LOGIN

                //Means invalid password
                return AuthenticationStatus.FailedOtherReason;
            }
            catch
            {
                if (principalContext == null)
                    return AuthenticationStatus.ServerUnreachable;

                return AuthenticationStatus.FailedOtherReason;
            }
        }

        /// <summary>
        /// Force expire password of a user
        /// </summary>
        /// <param name="sUserName">The username to expire the password</param>
        public UserAccountOperationStatus ExpireUserPassword(string username)
        {
            UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, username);

            if (userPrincipal == null)
                return UserAccountOperationStatus.InvalidUser;

            try
            {
                userPrincipal.ExpirePasswordNow();
                userPrincipal.Save();

                return UserAccountOperationStatus.Success;
            }
            catch
            {
                if (principalContext == null)
                    return UserAccountOperationStatus.ServerUnreachable;

                return UserAccountOperationStatus.FailedOtherReason;
            }
        }
        #endregion

        #region Private Helper
        private void Initialize()
        {
            try
            {
                string server = GetAppSettingValue("ActiveDirectoryPath");
                string userName = GetAppSettingValue("ActiveDirectoryUserName");
                string password = GetAppSettingValue("ActiveDirectoryPassword");
                string OU = GetAppSettingValue("ActiveDirectoryOU");

                newUserDefaultPassword = GetAppSettingValue("DefaultPasswordForNewUser");

                //  this.principalContext = new PrincipalContext(ContextType.Domain, server, userName, password);
                this.principalContext = new PrincipalContext(ContextType.Domain, server, OU, userName, password);
                //   this.userPrincipal = new UserPrincipal(this.principalContext, userName, password, true);
                this.userPrincipal = new UserPrincipal(this.principalContext, userName, password, true);
            }
            catch (PrincipalServerDownException ex)
            {
                //Server is down
            }
            catch
            {
                //General exception
            }
        }

        private string GetAppSettingValue(string settingKey)
        {
            return ConfigurationManager.AppSettings[settingKey];
        }

        public bool PasswordRequiresToBeChanged(UserPrincipal userPrincipal)
        {
            DirectoryEntry user = (DirectoryEntry)userPrincipal.GetUnderlyingObject(); //A directory entry pointing to the user
            Int64 pls;
            int uac;

            if (user != null && user.Properties["pwdLastSet"] != null && user.Properties["pwdLastSet"].Value != null)
            {
                pls = ConvertADSLargeIntegerToInt64(user.Properties["pwdLastSet"].Value);
            }
            else
            {
                throw new Exception("Could not determine if password needs reset");
            }

            if (user != null && user.Properties["UserAccountControl"] != null && user.Properties["UserAccountControl"].Value != null)
            {
                uac = (int)user.Properties["UserAccountControl"].Value;
            }
            else
            {
                throw new Exception("Could not determine if password needs reset");
            }

            return (pls == 0) && ((uac & 0x00010000) == 0) ? true : false;
        }

        private static Int64 ConvertADSLargeIntegerToInt64(object adsLargeInteger)
        {
            var highPart = (Int32)adsLargeInteger.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null);
            var lowPart = (Int32)adsLargeInteger.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null);
            return highPart * ((Int64)UInt32.MaxValue + 1) + lowPart;
        }

        #endregion

        #region Singleton
        private static ActiveDirectoryHelper instance;
        private static object lockObject = new object();

        /// <summary>
        /// Gets the singleton instance.
        /// </summary>
        public static ActiveDirectoryHelper Instance
        {
            get
            {
                lock (lockObject)
                {
                    if (instance == null || instance.principalContext == null)
                        instance = new ActiveDirectoryHelper();

                    return instance;
                }
            }
        }

        /// <summary>
        /// Cleans up the singleton instance so that when accessed next time, it gets recreated.
        /// </summary>
        public static void ForceCleanInstance()
        {
            lock (lockObject)
            {
                instance = null;
            }
        }
        #endregion
    }

}



For simple error management i created a code file named enum.cs and code goes below



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

#region Enums
/// <summary>
/// Represents the status of a particular user account.
/// </summary>
public enum UserAccountStatus
{
    Enable = 1,
    Disable = 0
}

/// <summary>
/// Represents the result of any operation performed against active directory.
/// </summary>
public enum ActionStatus
{
    Unknown = 0,
    Success = 1,
    Failure = -1,
    ServerUnreachable = -3
}

/// <summary>
/// Represents the authentication status of a particular user.
/// </summary>
public enum AuthenticationStatus
{
    Unknown = 0,
    Success = 1,
    FailedOtherReason = -1,
    AccountLockedOut = -2,
    InvalidUser = -3,
    ServerUnreachable = -4,
    PasswordNeedsToBeChanged = -5
}

/// <summary>
/// Represents the user creation status.
/// </summary>
public enum UserCreateStatus
{
    Unknown = 0,
    Created = 1,
    FailedOtherReason = -1,
    AlreadyExists = -2,
    PasswordPolicyViolated = -3,
    ServerUnreachable = -4
}

/// <summary>
/// Represents the password change status.
/// </summary>
public enum PasswordChangeStatus
{
    Unknown = 0,
    Changed = 1,
    InvalidUser = -1,
    InvalidPassword = -2,
    FailedOtherReason = -3,
    ServerUnreachable = -4
}

public enum UserAccountOperationStatus
{
    Unknown = 0,
    Success = 1,
    InvalidUser = -1,
    FailedOtherReason = -2,
    ServerUnreachable = -3
}
#endregion


Entry in web.config file are Username,Password,Path (IP), OU.

How to call AD Helper Class



  After so much RnD and Gooleing i created this class and it helped so much in my application.Hope it can serve you too... :)


If u had any trouble just ask, Happy to help u :)
Stay Tune...
Have a nice day... 'N happy Coding :)

No comments: