Add LDAP/Active Directory authentication support - #1869
Conversation
|
Thanks for the PR. Is there any specific reason to prefer using |
|
I used Novell because I was under impression it was more compatible. It was tested against Microsoft Servers LDAP, 2016, 2019, and 2022.
|
|
Thanks for the response. The concern I have here is that |
|
Would you like me to change it to use System.DirectoryServices.Protocols? |
That will be really nice. Also please rebase to the |
Adds native LDAP SSO authentication allowing users to sign in with their Active Directory or LDAP directory credentials. Supports plain LDAP, StartTLS (port 389), and LDAPS (port 636). Includes group-to- role mapping, configurable auto-provisioning, and full environment variable support for Docker deployments. Uses System.DirectoryServices.Protocols (Microsoft built-in library). On Linux, requires libldap2 to be installed.
294ee56 to
5211b4c
Compare
|
Hi, I've updated the PR as requested. Switched from Novell.Directory.Ldap to System.DirectoryServices.Protocols and rebased onto develop. Tested on Debian 13 with Active Directory. One Linux prerequisite: libldap2 needs to be installed (not included by the Technitium install script or the .NET runtime). On Debian/Ubuntu: Let me know if you need any changes. |
|
Thanks for the update! Will check it out soon. |
|
Hi Hemsby, may I ask if you've ever test against FreeIPA and OpenLDAP? As far as I know their directory attribute structure could be very different. The Active Directory query (including recursive query) method may not apply to FreeIPA or OpenLDAP |
LdapAuthProvider: fall back to a reverse group-membership search (member/uniqueMember/memberUid) when the user entry has no values for the configured group attribute. The default "memberOf" is an AD-native reverse-linked attribute; stock OpenLDAP (without the memberof overlay) doesn't populate it, so LDAP group-based role mapping was silently doing nothing on that directory even though login itself worked. Fallback is best-effort and only runs when the primary lookup found no groups, so directories that already populate memberOf (AD, OpenLDAP with the overlay) are unaffected. Extensions.cs: TryQueryOrFormArray's colspan overload threw a raw "Offset and length were out of bounds" exception when the submitted value wasn't an exact multiple of colspan entries (e.g. ldapGroupMap without the '|' delimiter). Now throws a clear DnsWebServiceException instead, surfaced through the existing API error handling. This is shared parsing code also used by ssoGroupMap and others, not LDAP specific, but was found while testing the LDAP config endpoint. Verified against a live OpenLDAP instance: both groupOfNames (member) and posixGroup (memberUid) group mappings now correctly elevate permissions without requiring the memberof overlay.
|
Good question, thanks for raising it. I tested this against a live OpenLDAP instance and found a real gap: basic authentication works fine out of the box (just set The reason: the default group attribute ( Fixed by adding a fallback: when the primary group attribute lookup on the user entry comes back empty, the code now does a reverse search for groups that list the user as a member ( I have not tested it specifically for FreeIPA. Also found and fixed an unrelated bug while testing: a malformed |
|
FreeIPA also has a bit different group membership structure than OpenLDAP. It has attribute called |
|
Thanks for the detail, that's really helpful. Good to know FreeIPA does maintain I'll deploy a FreeIPA instance to test against directly and get the code updated to handle it properly. |
|
I deployed a real FreeIPA instance (4.13.1) to test this properly rather than guess. Turns out What threw me initially is that To confirm end to end, I set up a nested group case (user is a direct member of a child group, which is nested inside a parent group) and mapped the parent group to a Technitium role. Login correctly picked up the indirect membership and applied the mapped permissions, using the unmodified PR code with no changes needed. So no code changes needed for FreeIPA, it already works correctly for group mapping including indirect membership. Thanks again for pointing this out, it was worth the real test to be sure rather than assume. This PR has now had complete, real world testing against Active Directory, FreeIPA, and OpenLDAP. |
|
That's nice to know that FreeIPA and OpenLDAP was tested and are working well. I am planning to test this PR soon so this really helps. |
Summary
Adds native LDAP authentication to the DNS Server web console, enabling users to sign in with their Active Directory or LDAP directory credentials.
Features
Use SSL+ port 636 = LDAPS,Use SSL+ any other port = StartTLS.user@domain) and full DN formats.(sAMAccountName={0})for Active Directory; any RFC 4515 filter is supported.Domain Admins→Administrators.DNS_SERVER_LDAP_*variables.Environment Variables
DNS_SERVER_LDAP_ENABLEDtrue/falseDNS_SERVER_LDAP_SERVERDNS_SERVER_LDAP_PORT389DNS_SERVER_LDAP_USE_SSLtrueenables StartTLS (port 389) or LDAPS (port 636)DNS_SERVER_LDAP_IGNORE_SSL_ERRORStrue/falseDNS_SERVER_LDAP_BIND_DNDNS_SERVER_LDAP_BIND_PASSWORDDNS_SERVER_LDAP_SEARCH_BASEDC=example,DC=comDNS_SERVER_LDAP_USER_FILTER(sAMAccountName={0})DNS_SERVER_LDAP_GROUP_ATTRIBUTEmemberOfDNS_SERVER_LDAP_ALLOW_SIGNUPtrue/falseDNS_SERVER_LDAP_ALLOW_SIGNUP_ONLY_FOR_MAPPED_USERStrue/falseDNS_SERVER_LDAP_GROUP_MAP[{"remoteGroup":"Domain Admins","localGroup":"Administrators"}]Implementation Notes
Uses
System.DirectoryServices.Protocols(Microsoft built-in library) for LDAP connectivity. On Linux, this requireslibldap2to be installed (apt install libldap2on Debian/Ubuntu,dnf install openldapon RHEL/Rocky). This package is not included by the Technitium install script but is available on all major Linux distributions.