How to Quickly Set Up a Test Active Directory Server for .NET Development


2 views

When developing .NET applications requiring Active Directory (AD) authentication, you don't need a full production AD setup. Here are the viable lightweight options:

  • AD LDS (Lightweight Directory Services) - Formerly ADAM, this is Microsoft's recommended solution for testing
  • Windows Server VM - Full AD experience but resource-heavy
  • Azure AD Free Tier - Cloud-based option with limited features

Here's the simplest way to get started with AD LDS:

# PowerShell commands to install AD LDS
Install-WindowsFeature -Name "ADLDS" -IncludeManagementTools

# Create a new AD LDS instance
Add-ADLDSInstance -InstanceName "TestAD" -Port 50000 -LdapPort 50001

Once your test AD is running, here's basic authentication code:

using System.DirectoryServices.AccountManagement;

bool AuthenticateUser(string username, string password)
{
    using (var context = new PrincipalContext(
        ContextType.Domain, 
        "localhost:50000", 
        "DC=test,DC=local"))
    {
        return context.ValidateCredentials(username, password);
    }
}

For automated testing, consider Docker containers with pre-configured AD:

docker run -d -p 389:389 -p 636:636 \
  --name test-ad \
  -e SAMBA_DOMAIN=test.local \
  -e SAMBA_ADMIN_PASSWORD=Passw0rd \
  nowsci/samba-domain
  • Port conflicts - Ensure your chosen ports (389, 636 etc.) are available
  • Certificate errors - For LDAPS, generate self-signed certs
  • Replication delays - Wait 15-30 seconds after changes

When developing .NET applications requiring AD authentication, you have several lightweight options:

  • Windows Server VM: The most complete solution using Hyper-V or VirtualBox
  • Azure AD Domain Services: Cloud-based managed AD (30-day free trial available)
  • AD LDS (Lightweight Directory Services): Formerly ADAM, runs on Windows 10/11 Pro
  • Docker Containers: Microsoft's ADDS-in-Docker image (Windows containers only)

For most development scenarios, AD LDS provides the best balance between authenticity and simplicity:

# PowerShell AD LDS setup
Install-WindowsFeature -Name "ADLDS" -IncludeManagementTools
$ldapPort = 389
$sslPort = 636
Adds-LdsInstance -InstanceName "DevAD" -Port $ldapPort -SSLPort $sslPort -ApplicationPartition "DC=dev,DC=local"

Here's basic authentication code using System.DirectoryServices:

using System.DirectoryServices;

bool AuthenticateUser(string username, string password)
{
    try {
        using (DirectoryEntry entry = new DirectoryEntry("LDAP://localhost:389/DC=dev,DC=local", 
               username, password))
        {
            using (DirectorySearcher searcher = new DirectorySearcher(entry))
            {
                searcher.Filter = $"(sAMAccountName={username})";
                SearchResult result = searcher.FindOne();
                return result != null;
            }
        }
    }
    catch {
        return false;
    }
}

Consider using Testcontainers for integration testing:

// NuGet: DotNet.Testcontainers
var activeDirectoryContainer = new TestcontainersBuilder<TestcontainersContainer>()
    .WithImage("microsoft/ad-dc-test")
    .WithPortBinding(389, 389)
    .Build();

await activeDirectoryContainer.StartAsync();
  • Ensure "Active Directory Lightweight Directory Services" Windows feature is enabled
  • For localhost testing, add "127.0.0.1 dev.local" to your hosts file
  • Use LDP.exe tool to verify your directory structure
  • Check Windows Event Viewer for AD LDS service errors

Create test users programmatically:

using (DirectoryEntry container = new DirectoryEntry("LDAP://CN=Users,DC=dev,DC=local"))
{
    DirectoryEntry user = container.Children.Add("CN=testuser", "user");
    user.Properties["sAMAccountName"].Value = "testuser";
    user.Properties["userPrincipalName"].Value = "testuser@dev.local";
    user.CommitChanges();
    user.Invoke("SetPassword", "P@ssw0rd");
    user.Properties["userAccountControl"].Value = 0x200; // NORMAL_ACCOUNT
    user.CommitChanges();
}