This project implements middleware for ASP.NET Core that enables authenticating users against LDAP directories like Active Directory via an LDAP bind.
There are two flavours, the first being Visus.LdapAuthentication, which uses Novell's C#-only LDAP library rather than the Windows-only DirectoryServices and is therefore running on Windows and Linux.
The second, Visus.DirectoryAuthentication, is a drop-in replacement using System.DirectorySerices.Protocols, which is a platform-independent implementation of LDAP services since .NET 5, but requires native LDAP libraries for P/Invoke being installed.
Built-in user objects are automatically mapped to Active Directory attributes based on code annotations and include commonly used claims like user name, actual names, e-mail addresses and group memberships. If necessary, you can also provide your own user object that uses a completely different mapping of LDAP attributes to claims.
See README for Visus.LdapAuthentication.
See README for Visus.DirectoryAuthentication
Version 2.0 is a major rewrite of both libraries, which removes previously deprecated functionality and unifies large parts of the implementation between LdapAuthentication and DirectoryAuthentication in the Visus.Ldap.Core
library. The most important changes to the 1.x branch are:
- Both libraries now require at least .NET 8.
- Besides the user object, which can be mapped to LDAP properties, a new group object allows for customising the mapping of group attributes as well. The indirection via the
ILdapUser
interface has been removed. - The mapping between LDAP entries and user/group objects is now performed by a
LdapMapper
class, which can be replaced by users of the library. The default implementation of the mapper uses reflection and the attribute annotations from previous versions of the library to support arbitrary user/group classes. - Similarly, the mapping between the user/group properties and
Claim
s is now performed by aClaimsBuilder
class, which can be replaced by users of the library. The default implementation of the builder uses reflection and the attribute annotations form previous versions of the library to support arbitrary user/group classes. - In addition to creating
Claim
s from user/group object, the library now supports direct creation ofClaim
s from LDAP entries via theClaimsMapper
, which can be replaced by users of the library. The default implementation of the mapper uses reflection and the attribute annotations from previous versions of the library to support arbitrary user/group classes. - The
ILdapOptions
interface has been removed. All configuration is performed via the common options pattern and theLdapOptions
class. - The library now provides a validator for the
LdapOptions
, which is exectued on startup, thus preventing the application from starting if obvious configuration errors have been made. - All services including the LDAP configuration are now injected by
AddLdapAuthentication
. Extension methods for adding subsets of the services have been removed. - Both libraries now use a
System.TimeSpan
for configuring timeouts. When configuring from JSON, use a string in the format "hh:mm:ss". - Both libraries now support and require an array of search bases.
- Both libraries now support and require an array of servers.
- Both libraries now support
async
/await
. - Both libraries support creation of
ClaimsPrincipal
s instead of custom user objects to facilitate the implementation of login controllers.
- In your LDAP options section in appsettings.json, make sure to change "Server" to "Servers" and provide an array of at least one server.
- In your LDAP options section in appsettings.json, make sure to change "SearchBase" to "SearchBases" and provide a map from the DN to the search scope.
- In your LDAP options section in appsettings.json, make sure to replace "IsSsl" with the equivalent "TransportSecurity". "IsSsl" is not honoured anymore! Without "TransportSecurity", your connections will not be encrypted!
- In your startup code, replace all previous dependency injection extension methods with a version of
AddLdapAuthentication
. The template parameters allow you to change the type of user and group that the LDAP entries are mapped to. - In your code, change all services to include the user and/or group type you want to use as generic parameters of the service interfaces.
- In your code, update the
using
statements. Some shared classes likeLdapUser
have been moved from theVisus.DirectoryAuthentication
andVisus.LdapAuthentication
namespaces to the sharedVisus.Ldap
namespace. Furthermore, the namespaces are now structured to isolate LDAP mapping, claims mapping, etc. - In your code, replace
ILdapAuthenticationService.Login
withILdapAuthenticationService.LoginUser
orILdapAuthenticationService.LoginPrincipal
depending on your needs. - If you use
LdapAttributeAttribute.GetLdapAttribute
to reflect on LDAP attribute mappings in your code, injectILdapAttributeMap<LdapUserOrGroup>
to obtain similar information.ILdapAttributeMap
s provide direct access to attribute names andPropertyInfo
s and are more efficient than the previous on-demand reflection.
Visus.DirectoryAuthentication and Visus.LdapAuthentication can mostly be used interchangeably with a few exceptions:
System.DirectorySerices.Protocols
requires native LDAP libraries for P/Invoke being installed. This should be the case for all Windows platforms by default, but on Linux,libldap
must be installed.- We found Visus.DirectoryAuthentication to be significantly faster on Windows systems than Visus.LdapAuthentication, particularly when using LDAPS. On Linux systems, however, we found that Visus.LdapAuthentication is usually more reliable than Visus.DirectoryAuthentication due to
System.DirectorySerices.Protocols
lacking a bunch of features on top oflibldap
. LdapOptions.RootCaThumbprint
is not supported. You can, however, check the immediate issuer of the server's certificate usingLdapOptions.ServerCertificateIssuer
.- Visus.DirectoryAuthentication supports different authentication types, which are dependent on the underlying native implementation, though. This can be configured via
LdapOptions.AuthenticationType
. - While Visus.DirectoryAuthentication relies on the underlying API to handle multiple servers, you can configure the behaviour of Visus.LdapAuthentication in your application settings via the
LdapOptions.ServerSelectionPolicy
.