Add X-Ldap-GroupDN for search user in group without memberOf.
This commit is contained in:
parent
ef8d313042
commit
55ce75a53e
11
README.md
11
README.md
|
|
@ -134,6 +134,17 @@ The reference implementation uses cookie-based authentication. If you are using
|
||||||
<strong>#</strong>proxy_set_header Cookie nginxauth=$cookie_nginxauth;
|
<strong>#</strong>proxy_set_header Cookie nginxauth=$cookie_nginxauth;
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
If you don't have memberOf in ldap and need check user in group by memberUid, set **X-Ldap-GroupDN**
|
||||||
|
|
||||||
|
```
|
||||||
|
proxy_set_header X-Ldap-GroupDN "cn=mygroup,ou=Group,dc=test,dc=com";
|
||||||
|
```
|
||||||
|
|
||||||
|
This will check if memberUid=username is in the specified group.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ case "$1" in
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SSDOPTS="--quiet --oknodo --background --no-close --make-pidfile --pidfile $PIDFILE --chuid $USER:$GROUP --exec $DAEMON"
|
SSDOPTS="--quiet --oknodo --background --no-close --make-pidfile --pidfile $PIDFILE --chuid $USER:$GROUP --exec $DAEMON"
|
||||||
DAEMON_ARGS="$URL $BASE $BIND_DN $BIND_PASS $COOKIE $FILTER $REALM"
|
DAEMON_ARGS="$URL $BASE $BIND_DN $BIND_PASS $COOKIE $FILTER $GROUPDN $REALM"
|
||||||
|
|
||||||
if start-stop-daemon --start $SSDOPTS -- $DAEMON_ARGS > $LOG 2>&1
|
if start-stop-daemon --start $SSDOPTS -- $DAEMON_ARGS > $LOG 2>&1
|
||||||
then
|
then
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ class LDAPAuthHandler(AuthHandler):
|
||||||
'basedn': ('X-Ldap-BaseDN', None),
|
'basedn': ('X-Ldap-BaseDN', None),
|
||||||
'template': ('X-Ldap-Template', '(cn=%(username)s)'),
|
'template': ('X-Ldap-Template', '(cn=%(username)s)'),
|
||||||
'binddn': ('X-Ldap-BindDN', ''),
|
'binddn': ('X-Ldap-BindDN', ''),
|
||||||
|
'groupdn': ('X-Ldap-GroupDN', ''),
|
||||||
'bindpasswd': ('X-Ldap-BindPass', ''),
|
'bindpasswd': ('X-Ldap-BindPass', ''),
|
||||||
'cookiename': ('X-CookieName', '')
|
'cookiename': ('X-CookieName', '')
|
||||||
}
|
}
|
||||||
|
|
@ -226,38 +227,63 @@ class LDAPAuthHandler(AuthHandler):
|
||||||
|
|
||||||
ctx['action'] = 'binding as search user'
|
ctx['action'] = 'binding as search user'
|
||||||
ldap_obj.bind_s(ctx['binddn'], ctx['bindpasswd'], ldap.AUTH_SIMPLE)
|
ldap_obj.bind_s(ctx['binddn'], ctx['bindpasswd'], ldap.AUTH_SIMPLE)
|
||||||
|
|
||||||
|
# Search memberUid in groupdn if defined
|
||||||
|
if ctx['groupdn']:
|
||||||
|
self.log_message('GroupDN defined to {}'.format(ctx['groupdn']))
|
||||||
|
|
||||||
|
ctx['action'] = 'preparing search filter'
|
||||||
|
searchfilter = "(memberUid=%s)" % ctx['user']
|
||||||
|
|
||||||
|
self.log_message(('searching on server "%s" with base dn ' +\
|
||||||
|
'"%s" with filter "%s"') %
|
||||||
|
(ctx['url'], ctx['groupdn'], searchfilter))
|
||||||
|
|
||||||
|
ctx['action'] = 'running search query in GroupDN'
|
||||||
|
results = ldap_obj.search_s(ctx['groupdn'], ldap.SCOPE_SUBTREE,
|
||||||
|
searchfilter, ['objectclass'], 1)
|
||||||
|
|
||||||
|
ctx['action'] = 'verifying search query results for GroupDN'
|
||||||
|
nres = len(results)
|
||||||
|
|
||||||
|
if nres < 1:
|
||||||
|
self.auth_failed(ctx, 'no memberUid found')
|
||||||
|
return
|
||||||
|
|
||||||
|
self.log_message("MemberUid found in GroupDN")
|
||||||
|
|
||||||
|
# Search filter
|
||||||
ctx['action'] = 'preparing search filter'
|
ctx['action'] = 'preparing search filter'
|
||||||
searchfilter = ctx['template'] % { 'username': ctx['user'] }
|
searchfilter = ctx['template'] % { 'username': ctx['user'] }
|
||||||
|
|
||||||
self.log_message(('searching on server "%s" with base dn ' + \
|
self.log_message(('searching on server "%s" with base dn ' + \
|
||||||
'"%s" with filter "%s"') %
|
'"%s" with filter "%s"') %
|
||||||
(ctx['url'], ctx['basedn'], searchfilter))
|
(ctx['url'], ctx['basedn'], searchfilter))
|
||||||
|
|
||||||
ctx['action'] = 'running search query'
|
ctx['action'] = 'running search query'
|
||||||
results = ldap_obj.search_s(ctx['basedn'], ldap.SCOPE_SUBTREE,
|
results = ldap_obj.search_s(ctx['basedn'], ldap.SCOPE_SUBTREE,
|
||||||
searchfilter, ['objectclass'], 1)
|
searchfilter, ['objectclass'], 1)
|
||||||
|
|
||||||
ctx['action'] = 'verifying search query results'
|
ctx['action'] = 'verifying search query results'
|
||||||
|
|
||||||
nres = len(results)
|
nres = len(results)
|
||||||
|
|
||||||
if nres < 1:
|
if nres < 1:
|
||||||
self.auth_failed(ctx, 'no objects found')
|
self.auth_failed(ctx, 'no objects found')
|
||||||
return
|
return
|
||||||
|
|
||||||
if nres > 1:
|
if nres > 1:
|
||||||
self.log_message("note: filter match multiple objects: %d, using first" % nres)
|
self.log_message("note: filter match multiple objects: %d, using first" % nres)
|
||||||
|
|
||||||
user_entry = results[0]
|
user_entry = results[0]
|
||||||
ldap_dn = user_entry[0]
|
ldap_dn = user_entry[0]
|
||||||
|
|
||||||
if ldap_dn == None:
|
if ldap_dn == None:
|
||||||
self.auth_failed(ctx, 'matched object has no dn')
|
self.auth_failed(ctx, 'matched object has no dn')
|
||||||
return
|
return
|
||||||
|
|
||||||
self.log_message('attempting to bind using dn "%s"' % (ldap_dn))
|
self.log_message('attempting to bind using dn "%s"' % (ldap_dn))
|
||||||
|
|
||||||
ctx['action'] = 'binding as an existing user "%s"' % ldap_dn
|
ctx['action'] = 'binding as an existing user "%s"' % ldap_dn
|
||||||
|
|
||||||
ldap_obj.bind_s(ldap_dn, ctx['pass'], ldap.AUTH_SIMPLE)
|
ldap_obj.bind_s(ldap_dn, ctx['pass'], ldap.AUTH_SIMPLE)
|
||||||
|
|
@ -313,6 +339,8 @@ if __name__ == '__main__':
|
||||||
group.add_argument('-f', '--filter', metavar='filter',
|
group.add_argument('-f', '--filter', metavar='filter',
|
||||||
default='(cn=%(username)s)',
|
default='(cn=%(username)s)',
|
||||||
help="LDAP filter (Default: cn=%%(username)s)")
|
help="LDAP filter (Default: cn=%%(username)s)")
|
||||||
|
group.add_argument('-g', metavar='groupdn', dest="groupdn", default='',
|
||||||
|
help="LDAP groupDN that must contain the memberUid=username (Default: unset)")
|
||||||
# http options:
|
# http options:
|
||||||
group = parser.add_argument_group(title="HTTP options")
|
group = parser.add_argument_group(title="HTTP options")
|
||||||
group.add_argument('-R', '--realm', metavar='"Restricted Area"',
|
group.add_argument('-R', '--realm', metavar='"Restricted Area"',
|
||||||
|
|
@ -330,6 +358,7 @@ if __name__ == '__main__':
|
||||||
'disable_referrals': ('X-Ldap-DisableReferrals', args.disable_referrals),
|
'disable_referrals': ('X-Ldap-DisableReferrals', args.disable_referrals),
|
||||||
'basedn': ('X-Ldap-BaseDN', args.basedn),
|
'basedn': ('X-Ldap-BaseDN', args.basedn),
|
||||||
'template': ('X-Ldap-Template', args.filter),
|
'template': ('X-Ldap-Template', args.filter),
|
||||||
|
'groupdn': ('X-Ldap-GroupDN', args.groupdn),
|
||||||
'binddn': ('X-Ldap-BindDN', args.binddn),
|
'binddn': ('X-Ldap-BindDN', args.binddn),
|
||||||
'bindpasswd': ('X-Ldap-BindPass', args.bindpw),
|
'bindpasswd': ('X-Ldap-BindPass', args.bindpw),
|
||||||
'cookiename': ('X-CookieName', args.cookie)
|
'cookiename': ('X-CookieName', args.cookie)
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ http {
|
||||||
# cookiename X-CookieName
|
# cookiename X-CookieName
|
||||||
# realm X-Ldap-Realm
|
# realm X-Ldap-Realm
|
||||||
# template X-Ldap-Template
|
# template X-Ldap-Template
|
||||||
|
# groupdn X-Ldap-GroupDN
|
||||||
|
|
||||||
# (Required) Set the URL and port for connecting to the LDAP server,
|
# (Required) Set the URL and port for connecting to the LDAP server,
|
||||||
# by replacing 'example.com'.
|
# by replacing 'example.com'.
|
||||||
|
|
@ -116,6 +117,11 @@ http {
|
||||||
# nginx-ldap-auth-daemon.py.
|
# nginx-ldap-auth-daemon.py.
|
||||||
#proxy_set_header X-Ldap-Template "(cn=%(username)s)";
|
#proxy_set_header X-Ldap-Template "(cn=%(username)s)";
|
||||||
|
|
||||||
|
# Optional. If you don't have memberOf in ldap
|
||||||
|
# and need check user in group by memberUid
|
||||||
|
# proxy_set_header X-Ldap-GroupDN "cn=mygroup,ou=Group,dc=test,dc=com";
|
||||||
|
|
||||||
|
|
||||||
# (Optional) Set the realm name, by uncommenting the following
|
# (Optional) Set the realm name, by uncommenting the following
|
||||||
# directive and replacing 'Restricted' which is the default set
|
# directive and replacing 'Restricted' which is the default set
|
||||||
# in nginx-ldap-auth-daemon.py.
|
# in nginx-ldap-auth-daemon.py.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#BIND_PASS="-w secret"
|
#BIND_PASS="-w secret"
|
||||||
#COOKIE="-c nginxauth"
|
#COOKIE="-c nginxauth"
|
||||||
#FILTER="-f (cn=%(username)s)"
|
#FILTER="-f (cn=%(username)s)"
|
||||||
|
#GROUPDN="-g cn=mygroup,ou=Group,dc=test,dc=com"
|
||||||
#REALM="-R 'Restricted Area'"
|
#REALM="-R 'Restricted Area'"
|
||||||
|
|
||||||
# these are used with init scripts only
|
# these are used with init scripts only
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ User=nginx-ldap-auth
|
||||||
Group=nginx-ldap-auth
|
Group=nginx-ldap-auth
|
||||||
WorkingDirectory=/var/run
|
WorkingDirectory=/var/run
|
||||||
EnvironmentFile=/etc/default/nginx-ldap-auth
|
EnvironmentFile=/etc/default/nginx-ldap-auth
|
||||||
ExecStart=/usr/bin/nginx-ldap-auth-daemon $URL $BASE $BIND_DN $BIND_PASS $COOKIE $FILTER $REALM
|
ExecStart=/usr/bin/nginx-ldap-auth-daemon $URL $BASE $BIND_DN $BIND_PASS $COOKIE $FILTER $GROUPDN $REALM
|
||||||
KillMode=process
|
KillMode=process
|
||||||
KillSignal=SIGINT
|
KillSignal=SIGINT
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue