jupyterhub / ldapauthenticator

LDAP Authenticator Plugin for Jupyter
BSD 3-Clause "New" or "Revised" License
206 stars 178 forks source link

Allowed groups doesn't work because user cn and memberuid are not same #137

Closed tanmaymathur89 closed 2 months ago

tanmaymathur89 commented 5 years ago

JupyterHub configuration:

c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.server_address = 'xxx'
c.LDAPAuthenticator.allowed_groups = [
    "CN=xxx,OU=Groups,DC=xyz,DC=com",
]
c.LDAPAuthenticator.use_ssl = True
c.LDAPAuthenticator.lookup_dn = True
c.LDAPAuthenticator.user_search_base = 'DC=xyz,DC=com'
c.LDAPAuthenticator.user_attribute = 'sAMAccountName'
c.LDAPAuthenticator.bind_dn_template = ['CN={username},OU=People,DC=xyz,DC=com']
c.LDAPAuthenticator.lookup_dn_search_filter = '(&(objectCategory=Person)({login_attr}={login}))'
c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'CN'

ldapsearch result:

# extended LDIF
#
# LDAPv3
# base <DC=xyz,DC=com> with scope subtree
# filter: (&(objectCategory=Person)(CN=Tanmay Mathur))
# requesting: ALL
#

# Tanmay Mathur, People, xyz.com
dn: CN=Tanmay Mathur, OU=People,DC=xyz,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: userProxyFull
cn: Tanmay Mathur
distinguishedName: CN=Tanmay Mathur,OU=People,DC=xyz,DC=com
instanceType: 4
whenCreated: xxx
whenChanged: xxx
displayName: Tanmay Mathur
uSNCreated: xxx
uSNChanged: xxx
name: Tanmay Mathur
objectGUID:: xxx
objectSid:: xxx
userPrincipalName: tmathur@xyz.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,CN=xxx
dSCorePropagationData: xxx
gidNumber: xxx
sAMAccountName: tmathur
uid: tmathur
homeDirectory: xxx
unixHomeDirectory: xxx
mail: tmathur@xyz.com
uidNumber: xxx
givenName: Tanmay
gecos: tmathur
sn: Mathur

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Since username gets overwritten with the CN name in the code, allowed groups filtering fails for me. I have changed my local code so the username doesn't get overwritten and it runs successfully.

dmpe commented 4 years ago

Facing exactly same issue here. My CN is "First Last" while user login which user uses to login is some sort of sAMAccountName, e.g. "abc".

I would need a capability ( this is from a helm chart) to say for example:

auth:
  type: ldap
  ldap:
    allowedGroups: 
      - 'CN=xxx,OU=Groups,DC=xyz,DC=com'
    server:
      address: x
      port: 389
      ssl: false
    dn:
      templates: 
        "CN={sAMAccountName},OU=......"

Thus, because of this missing functionality, I can not setup group filtering. The LDAP auth itself works quite well. @minrk @yuvipanda any ideas on that ?

tanmaymathur89 commented 4 years ago

I forked the repo and modified ldapauthenticator. I can create an PR if we agree to fix this bug.

Ownercz commented 4 years ago

@tanmaymathur89 do you have the code of your modification published somewhere? I also encountered this issue. Thanks

tanmaymathur89 commented 4 years ago

@Ownercz Unfortunately I don't have the code available in a public repo

brindapabari commented 4 years ago

I forked the repo and modified ldapauthenticator. I can create an PR if we agree to fix this bug.

@tanmaymathur89 Could you please let me know where have you made the changes to enable such a requirement? I am facing the same issue

brindapabari commented 4 years ago

I got this working today. For anyone who might be going through the same issue where Allowed groups do not work because user CN and username or uid are not same. In my case, for example the user is John Smith, the username is samaccountname. The value used to login is "DOMAIN\js1234" and the CN ="John Smith".

When I set the c.LDAPAuthenticator.lookup_dn = True, it did not work because the dn was constructed out of the username that I passed while logging in, i.e., "DOMAIN\js1234". dn is checked for allowed groups filtering. This can be an issue in active directory where the samaccoutname is not a part of the full dn of that user and this mismatch results in user not being found in the groups.

For this I kept c.LDAPAuthenticator.bind_dn_template blank and instead provided a service account username and password in the configuration with following:

c.LDAPAuthenticator.lookup_dn_search_user = "DOMAIN\<serviceaccount>"
c.LDAPAuthenticator.lookup_dn_search_password = "<pwd>"
c.LDAPAuthenticator.lookup_dn_search_user = True
c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'sAMAccountName'

c.LDAPAuthenticator.allowed_groups = ["CN=abc,OU=abc,DC=abc,DC=abc"]

When you don't explicitly pass the bind_dn_template and use service account username and password in the config--it will query ldap and fetch the DN. if the bind_dn_template is passed, the fetched one is overwritten with what you passed in config file. Also, for most of the active directory configurations, anonymous query is not allowed.

Additional troubleshooting steps that can helpful: Try checking out the /ldapauthenticator.py file which will be in /usr/bin/python3.x/site packages/ldapauthenticator to understand the flow of authentication and what attribute values are used for ldap bind. This is the first time I was configuring jupyterhub with LDAP and I used multiple print statements and ran jupyterhub in debug mode to get those and understanding each attribute value that is passed through jupyterhub_config.py.

stelukutla commented 4 years ago

@brindapabari How is your final template looks like?

wiltonsr commented 3 years ago

Just define

c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'distinguishedName'

I use ldapauthenticator v1.3.2 and Jupyter together with Active Directory and allowed_groups works fine.

This is my complete config, obtained from here:

c.LDAPAuthenticator.lookup_dn = True
c.LDAPAuthenticator.lookup_dn_search_filter = '({login_attr}={login})'
c.LDAPAuthenticator.lookup_dn_search_user = 'USE_YOUR_SERVICE_ACCOUNT_HERE'
c.LDAPAuthenticator.lookup_dn_search_password = 'USE_YOUR_SERVICE_PASS_HERE'
c.LDAPAuthenticator.user_search_base = 'ou=example,dc=com'
c.LDAPAuthenticator.user_attribute = 'sAMAccountName'
c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'distinguishedName'
c.LDAPAuthenticator.escape_userdn = False
c.LDAPAuthenticator.bind_dn_template = '{username}'
c.LDAPAuthenticator.use_lookup_dn_username = False
# When authenticating on a Linux machine against an AD server 
# This might return something different from the supplied UNIX username. 
# In this case setting use_lookup_dn_username to False might be a solution.

Just check if you AD server hash attribute distinguishedName, but based on this I believe it has.

wiltonsr commented 3 years ago

I read #199 and just remove

c.LDAPAuthenticator.bind_dn_template = '{username}'

and setting

c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'cn'

has the same result.

consideRatio commented 2 months ago

Old and possibly resolved by comments, closing.