How to authenticate users in nested groups in Apache LDAP?

Solution 1:

Besides AuthLDAPSubGroupDepth, that is available only in apache 2.4, it is possible, when using Microsoft AD LDAP, to do authorization using nested groups by using LDAP_MATCHING_RULE_IN_CHAIN matching rule. This is much faster than searching subgroups on the client, because it is done on the DC server with less queries over network.

Require ldap-filter memberof:1.2.840.113556.1.4.1941:=CN=Access to Apache,OU=My Organization Unit,DC=company,DC=com

The string 1.2.840.113556.1.4.1941 is an OID called LDAP_MATCHING_RULE_IN_CHAIN. This OID is assigned by Microsoft to be used with its LDAP implementation (part of Active Directory). You can not use it with other LDAP servers. The human redeable format is: iso(1).member_body(2).us(840).microsoft(113556).ad(1).as_schema(4).LDAP_MATCHING_RULE_IN_CHAIN(1941)

From Microsoft documentation:

This rule is limited to filters that apply to the DN. This is a special "extended" match operator that walks the chain of ancestry in objects all the way to the root until it finds a match.

See also:


Solution 2:

You need to set AuthLDAPSubGroupDepth to make this work. The integer you provide here specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.

Add this to your config:

AuthLDAPSubGroupDepth 1

More Info: here and here.

Solution 3:

It looks like your only option in Apache 2.2 is to list every group that is included by your main authorized group.

Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local
Require ldap-group  CN=MyOtherGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local

This should be reasonable if your nested groups aren't too complicated.

Crossing AD Domains(using two LDAP servers)

You can set up OpenLDAP with the slapd_meta overlay running on your web server to proxy your authentication.

/etc/ldap/slapd.conf should look something like:

database meta
suffix   "DC=company,DC=local"
uri      "ldap://,DC=company,DC=local"
uri      "ldap://,DC=company,DC=local"

Then, your mod_authnz_ldap stanza would look something like:

AuthName            "whatever"
AuthType            Basic
AuthBasicProvider   ldap
AuthLDAPUrl         "ldapi:///DC=company,DC=local?sAMAccountName?sub?(objectClass=*)"
Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local
Require ldap-group  CN=MyOtherGroup,OU=Security Groups,OU=otherdomainsuffix,DC=company,DC=local

This will require some massaging to get it to work, but I think this is the general idea.

Solution 4:

While the solution provided by @Mircea_Vutcovici worked for me, my only criticism is that people may get squeamish when they see bitwise operators in use.

For instance, I'll be handing over an Apache Bloodhound installation, that uses Apache HTTPd as the front end with AD group auth, to a group of fellow developers. They're going to have issues coming to grips with bitwise operators. Admins will not be as squeamish of course...I hope.

That being said, I have a solution that doesn't use the bitwise operator and that doesn't use multiple ldap-group definitions.

The following config works for me:

<Location /protected>
    # Using this to bind
    AuthLDAPURL "ldap://<MY_SERVER>:3268/<MY_SEARCH_BASE>?sAMAccountName?sub?(objectClass=user)"
    AuthLDAPBindDN "<MY_BIND_DN>"
    AuthLDAPBindPassword "<MY_PASSWORD>"
    LDAPReferrals Off

    AuthType Basic
    AuthBasicProvider ldap
    Require ldap-group <MY_PARENT_GROUP>
    AuthLDAPMaxSubGroupDepth 1
    AuthLDAPSubgroupAttribute member
    AuthLDAPSubGroupClass group
    AuthLDAPGroupAttribute member
    AuthLDAPGroupAttributeIsDN on

The critical part was the following config:

AuthLDAPSubGroupClass group

AuthLDAPMaxSubGroupDepth doesn't work by itself, nor when coupled with AuthLDAPSubgroupAttribute. It was only when I used AuthLDAPSubGroupClass that auth against sub groups started least for me and my situation.