Linger.Ldap.ActiveDirectory
2.0.0-preview.1
dotnet add package Linger.Ldap.ActiveDirectory --version 2.0.0-preview.1
NuGet\Install-Package Linger.Ldap.ActiveDirectory -Version 2.0.0-preview.1
<PackageReference Include="Linger.Ldap.ActiveDirectory" Version="2.0.0-preview.1" />
<PackageVersion Include="Linger.Ldap.ActiveDirectory" Version="2.0.0-preview.1" />
<PackageReference Include="Linger.Ldap.ActiveDirectory" />
paket add Linger.Ldap.ActiveDirectory --version 2.0.0-preview.1
#r "nuget: Linger.Ldap.ActiveDirectory, 2.0.0-preview.1"
#:package Linger.Ldap.ActiveDirectory@2.0.0-preview.1
#addin nuget:?package=Linger.Ldap.ActiveDirectory&version=2.0.0-preview.1&prerelease
#tool nuget:?package=Linger.Ldap.ActiveDirectory&version=2.0.0-preview.1&prerelease
Linger.Ldap.ActiveDirectory
Breaking changes and 2.0 migration notes are documented in the Linger migration guide.
An Active Directory focused LDAP client implementation based on System.DirectoryServices.
Features
- Active Directory user authentication and validation
- Synchronous user lookup and search APIs matching the underlying Windows provider
- OU-scoped search support via
searchBase - Optional
Attributesprojection to limit returned fields - LDAPS support via
LdapConfig.Security - Configurable
SearchFilterforFindUserandGetUsers - Advanced query via
IActiveDirectoryClient.SearchUsersByFilter - Optional domain controller auto-discovery when
LdapConfig.Urlis empty - Parameterless construction for the current Windows domain
- Configurable
MaxResultslimit for each query
Supported Frameworks
- .NET 10.0
- .NET 9.0
- .NET 8.0
- .NET Standard 2.0
Installation
dotnet add package Linger.Ldap.ActiveDirectory
Quick Start
using Linger.Ldap.ActiveDirectory;
using Linger.Ldap.Contracts;
var config = new LdapConfig
{
Url = "example.com",
Domain = "example",
SearchBase = "DC=example,DC=com",
SearchFilter = "(&(objectClass=user)(sAMAccountName={0}))",
Security = true,
MaxResults = 1000,
Credentials = new LdapCredentials
{
BindDn = "serviceAccount",
BindCredentials = "SecurePassword123!"
},
Attributes =
[
"displayName",
"sAMAccountName",
"mail",
"department",
"memberOf"
]
};
var ldap = new AdLdapClient(config);
For the current Windows domain, configuration is optional:
var ldap = new AdLdapClient();
The parameterless constructor performs no network I/O. It uses the current Windows identity and discovers a domain controller when the first LDAP operation starts.
For dependency injection, register LdapConfig with services.Configure<LdapConfig>(...) and AdLdapClient as the IActiveDirectoryClient implementation. The client consumes IOptions<LdapConfig> directly.
Usage
Validate User Credentials
var (isValid, userInfo) = ldap.ValidateUser("alice", "Password123!");
if (isValid && userInfo is not null)
{
Console.WriteLine($"DisplayName: {userInfo.DisplayName}");
Console.WriteLine($"Email: {userInfo.Email}");
}
Authentication is determined by ValidateCredentials. User information is queried separately with the configured search credentials. If that query is unavailable or unauthorized, the method returns IsValid = true and userInfo = null.
Find a Single User
var user = ldap.FindUser("alice");
if (user is not null)
{
Console.WriteLine($"SamAccountName: {user.SamAccountName}");
Console.WriteLine($"DN: {user.Dn}");
}
Search Users
var users = ldap.GetUsers("alice");
foreach (var item in users)
{
Console.WriteLine($"{item.DisplayName} ({item.Email})");
}
Search in a Specific OU with Custom Bind Credentials
var customCreds = new LdapCredentials
{
BindDn = "readonly.user",
BindCredentials = "ReadonlyPassword123!"
};
var usersInOu = ldap.GetUsers(
"alice",
ldapCredentials: customCreds,
searchBase: "OU=Sales,DC=example,DC=com");
Advanced Filter Search
IActiveDirectoryClient ldapContract = ldap;
var users = ldapContract.SearchUsersByFilter(
"(&(objectClass=person)(department=IT)(mail=*))",
searchBase: "DC=example,DC=com");
Notes
- This implementation is intended for Windows environments using
System.DirectoryServices. - In .NET 5+, the implementation is marked with
[SupportedOSPlatform("windows")]. - When
Security = true, the client enablesAuthenticationTypes.SecureSocketsLayeron the ADSI connection. SearchFilteris used by bothFindUserandGetUsers; using{0}placeholder is recommended.SearchUsersByFilterprovides raw-filter queries for Active Directory.- Blank usernames and raw filters are rejected to prevent accidental full-directory searches.
- Operations are synchronous because
System.DirectoryServicesdoes not provide asynchronous search APIs. - If
SearchFilterformat is invalid, the implementation falls back to a default user filter. - Input value in user search is escaped before building LDAP filter to reduce malformed/injection risk.
- Bind username normalization supports existing
domain\\user, UPN (user@domain), and full DN forms. - If
LdapConfig.Urlis empty, Active Directory provider attempts domain controller auto-discovery. - The parameterless constructor leaves
SearchBaseempty and searches from the discovered server root.SearchBaseis not inferred; use configured construction to restrict the search scope. MaxResultsmust be greater than zero and limits each query; the default is1000.- Configuration is snapshotted during client construction. Changes to the original
LdapConfig, credentials, or attributes require a new client. - Search-operation connection, bind, and directory-server failures throw exceptions. An empty list only means that no users matched.
Key User Properties (LdapUserInfo)
DisplayName,SamAccountName,Upn,DnEmail,TelephoneNumber,Mobile,Department,TitleCompany,Manager,WhenCreated,Status,PwdLastSetMemberOf,ProxyAddresses,OtherTelephone,ProfilePath,HomeDirectory,ExtensionAttribute1
MemberOf, ProxyAddresses, and OtherTelephone preserve LDAP multi-values as string arrays.
Dependencies
- System.DirectoryServices
- System.DirectoryServices.AccountManagement
- Linger.Ldap.Contracts
Related Packages
- Linger.Ldap.Contracts: core LDAP interfaces and data models
- Linger.Ldap.Novell: cross-platform LDAP implementation based on Novell library
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Linger.Ldap.Contracts (>= 2.0.0-preview.1)
- Linger.Utils (>= 2.0.0-preview.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- System.DirectoryServices (>= 10.0.10)
- System.DirectoryServices.AccountManagement (>= 10.0.10)
-
net10.0
- Linger.Ldap.Contracts (>= 2.0.0-preview.1)
- Linger.Utils (>= 2.0.0-preview.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- System.DirectoryServices (>= 10.0.10)
- System.DirectoryServices.AccountManagement (>= 10.0.10)
-
net8.0
- Linger.Ldap.Contracts (>= 2.0.0-preview.1)
- Linger.Utils (>= 2.0.0-preview.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- System.DirectoryServices (>= 10.0.10)
- System.DirectoryServices.AccountManagement (>= 10.0.10)
-
net9.0
- Linger.Ldap.Contracts (>= 2.0.0-preview.1)
- Linger.Utils (>= 2.0.0-preview.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options (>= 10.0.10)
- System.DirectoryServices (>= 10.0.10)
- System.DirectoryServices.AccountManagement (>= 10.0.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0-preview.1 | 36 | 8/29/2026 |
| 1.6.4 | 104 | 8/16/2026 |
| 1.6.3 | 103 | 8/5/2026 |
| 1.6.2 | 112 | 8/2/2026 |
| 1.6.0 | 101 | 7/25/2026 |
| 1.5.5 | 106 | 7/23/2026 |
| 1.5.4-preview | 95 | 7/21/2026 |
| 1.5.3-preview | 93 | 7/20/2026 |
| 1.5.2-preview | 95 | 7/19/2026 |
| 1.5.1-preview | 93 | 7/15/2026 |
| 1.5.0-preview | 90 | 7/14/2026 |
| 1.4.4-preview | 103 | 6/16/2026 |
| 1.4.3-preview | 99 | 6/15/2026 |
| 1.4.2 | 119 | 5/20/2026 |
| 1.4.1-preview | 112 | 5/12/2026 |
| 1.4.0 | 118 | 5/6/2026 |
| 1.3.3-preview | 102 | 5/5/2026 |
| 1.3.2-preview | 106 | 4/29/2026 |
| 1.3.1-preview | 111 | 4/28/2026 |
| 1.3.0-preview | 102 | 4/27/2026 |