etianen / django-python3-ldap

Django LDAP user authentication backend for Python 3.
BSD 3-Clause "New" or "Revised" License
411 stars 120 forks source link

Can I log in without using AUTHENTICATION_BACKENDS? #239

Open Plaoo opened 2 years ago

Plaoo commented 2 years ago

Hi everyone, I'm trying to implement LDAP on a project that uses rest framework, as the documentation says, you need to add AUTHENTICATION_BACKENDS, but if I do I can't log in from the frontend.

In the settings it is set like this

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
         'django_rest_multitokenauth.coreauthentication.MultiTokenAuthentication',
         'rest_framework.authentication.BasicAuthentication',

    )
}

If add

AUTHENTICATION_BACKENDS = (
    'django_python3_ldap.auth.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

I can't log in normally anymore and if I add 'django_python3_ldap.auth.LDAPBackend', to DEFAULT_AUTHENTICATION_CLASSES, same.

This is my ldap settings on django settings:


LDAP_AUTH_URL  = "ldap://172.17.0.1:389"
LDAP_AUTH_USE_TLS = False

LDAP_AUTH_SEARCH_BASE = "cn=admin,dc=example,dc=org"
#LDAP_AUTH_SEARCH_BASE = "dc=example,dc=org"
# The LDAP class that represents a user.
LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson"

# User model fields mapped to the LDAP
# attributes that represent them.
LDAP_AUTH_USER_FIELDS = {
    "username": "uid",
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
}

# A tuple of django model fields used to uniquely identify a user.
LDAP_AUTH_USER_LOOKUP_FIELDS = ("username",)

# Path to a callable that takes a dict of {model_field_name: value},
# returning a dict of clean model data.
# Use this to customize how data loaded from LDAP is saved to the User model.
LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data"

# Path to a callable that takes a user model, a dict of {ldap_field_name: [value]}
# a LDAP connection object (to allow further lookups), and saves any additional
# user relationships based on the LDAP data.
# Use this to customize how data loaded from LDAP is saved to User model relations.
# For customizing non-related User model fields, use LDAP_AUTH_CLEAN_USER_DATA.
LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations"

# Path to a callable that takes a dict of {ldap_field_name: value},
# returning a list of [ldap_search_filter]. The search filters will then be AND'd
# together when creating the final search filter.
LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters"

# Path to a callable that takes a dict of {model_field_name: value}, and returns
# a string of the username to bind to the LDAP server.
# Use this to support different types of LDAP server.
LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_openldap"

# Sets the login domain for Active Directory users.
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = None

# The LDAP username and password of a user for querying the LDAP database for user
# details. If None, then the authenticated user will be used for querying, and
# the `ldap_sync_users` command will perform an anonymous query.
LDAP_AUTH_CONNECTION_USERNAME = 'cn=admin,dc=example,dc=org'
LDAP_AUTH_CONNECTION_PASSWORD = 'admin'

#LDAP_AUTH_CONNECTION_USERNAME = "admin"
#LDAP_AUTH_CONNECTION_PASSWORD = "admin"

# Set connection/receive timeouts (in seconds) on the underlying `ldap3` library.
LDAP_AUTH_CONNECT_TIMEOUT = None
LDAP_AUTH_RECEIVE_TIMEOUT = None

#LDAP Config End ------

commands: docker-compose exec stip_company python manage.py ldap_sync_users

return

CommandError: Could not connect to LDAP server

from ldap server

openldap        | 6225df35 conn=1049 fd=12 ACCEPT from IP=172.25.0.1:47262 (IP=0.0.0.0:389)
openldap        | 6225df35 conn=1049 op=0 BIND dn="mail=cn\3Dadmin\2Cdc\3Dexample\2Cdc\3Dorg,cn=users,ou=group,dc=example,dc=org" method=128
openldap        | 6225df35 conn=1049 op=0 RESULT tag=97 err=49 text=
openldap        | 6225df3a conn=1049 op=1 UNBIND
openldap        | 6225df3a conn=1049 fd=12 closed

UPDATE: I tried to connect using the lib ldap3 and I succeeded. The difference is in the logs ldap connection:

In [9]: >>> from ldap3 import Server, Connection, ALL
   ...: >>> server = Server('localhost', get_info=ALL)
   ...: >>> conn = Connection(server, 'cn=admin,dc=example,dc=org', 'admin', auto_bind=True)
   ...: >>> conn.search('ou=group,dc=example,dc=org', '(objectclass=inetOrgPerson)')
Out[9]: True

log:

openldap        | 622632c5 conn=1241 fd=14 ACCEPT from IP=172.25.0.1:47450 (IP=0.0.0.0:389)
openldap        | 622632c5 conn=1241 op=0 BIND dn="cn=admin,dc=example,dc=org" method=128
openldap        | 622632c5 conn=1241 op=0 BIND dn="cn=admin,dc=example,dc=org" mech=SIMPLE ssf=0
openldap        | 622632c5 conn=1241 op=0 RESULT tag=97 err=0 text=
openldap        | 622632c5 conn=1241 op=1 SRCH base="" scope=0 deref=3 filter="(objectClass=*)"
openldap        | 622632c5 conn=1241 op=1 SRCH attr=altServer namingContexts supportedControl supportedExtension supportedFeatures supportedCapabilities supportedLdapVersion supportedSASLMechanisms vendorName vendorVersion subschemaSubentry * + +
openldap        | 622632c5 conn=1241 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
openldap        | 622632c5 conn=1241 op=2 SRCH base="cn=Subschema" scope=0 deref=3 filter="(objectClass=subschema)"
openldap        | 622632c5 conn=1241 op=2 SRCH attr=objectClasses attributeTypes ldapSyntaxes matchingRules matchingRuleUse dITContentRules dITStructureRules nameForms createTimestamp modifyTimestamp * +
openldap        | 622632c5 conn=1241 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text=
openldap        | 622632c5 conn=1241 op=3 SRCH base="ou=group,dc=example,dc=org" scope=2 deref=3 filter="(objectClass=inetOrgPerson)"
openldap        | 622632c5 conn=1241 op=3 SRCH attr=1.1
openldap        | 622632c5 conn=1241 op=3 SEARCH RESULT tag=101 err=0 nentries=3 text=

if I try with django:

openldap        | 62263235 conn=1240 fd=14 ACCEPT from IP=172.25.0.1:47448 (IP=0.0.0.0:389)
openldap        | 62263235 conn=1240 op=0 BIND dn="mail=cn\3Dadmin\2Cdc\3Dexample\2Cdc\3Dorg,cn=admin,dc=example,dc=org" method=128
openldap        | 62263235 conn=1240 op=0 RESULT tag=97 err=49 text=
openldap        | 62263239 conn=1240 op=1 UNBIND
openldap        | 62263239 conn=1240 fd=14 closed

I think this is the problem openldap | 62263235 conn=1240 op=0 BIND dn="mail=cn\3Dadmin\2Cdc\3Dexample

etianen commented 2 years ago

Please enable logging and paste the log output into this issue.

https://github.com/etianen/django-python3-ldap#logging

Sorry for the delay in replying!

On Mon, 7 Mar 2022 at 10:39, Paolo Monni @.***> wrote:

Hi everyone, I'm trying to implement LDAP on a project that uses rest framework, as the documentation says, you need to add AUTHENTICATION_BACKENDS, but if I do I can't log in from the frontend.

In the settings it is set like this

REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'django_rest_multitokenauth.coreauthentication.MultiTokenAuthentication', 'rest_framework.authentication.BasicAuthentication',

)

}

If add

AUTHENTICATION_BACKENDS = ( 'django_python3_ldap.auth.LDAPBackend', 'django.contrib.auth.backends.ModelBackend', )

I can't log in normally anymore and if I add 'django_python3_ldap.auth.LDAPBackend', to DEFAULT_AUTHENTICATION_CLASSES, same.

This is my ldap settings on django settings:

LDAP Config ---

docker0LDAP_AUTH_URL = "ldap://172.17.0.1:389"LDAP_AUTH_USE_TLS = False

LDAP_AUTH_SEARCH_BASE = "cn=users,ou=group,dc=example,dc=org"#LDAP_AUTH_SEARCH_BASE = "ou=group,dc=example,dc=org"#LDAP_AUTH_SEARCH_BASE = "dc=example,dc=org" LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson" LDAP_AUTH_USER_FIELDS = { "username": "uid", "first_name": "givenName", "last_name": "sn", "email": "mail", }

A tuple of django model fields used to uniquely identify a user.LDAP_AUTH_USER_LOOKUP_FIELDS = ("email", "password")

LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data" LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations" LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters"LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_openldap"LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = None

The LDAP username and password of a user for querying the LDAP database for user# details. If None, then the authenticated user will be used for querying, and# the ldap_sync_users command will perform an anonymous query.LDAP_AUTH_CONNECTION_USERNAME = 'cn=admin,dc=example,dc=org'LDAP_AUTH_CONNECTION_PASSWORD = 'admin'LDAP_AUTH_OBJECT_CLASS = "operator"# Set connection/receive timeouts (in seconds) on the underlying ldap3 library.LDAP_AUTH_CONNECT_TIMEOUT = NoneLDAP_AUTH_RECEIVE_TIMEOUT = None

LDAP Config End ---

commands: docker-compose exec stip_company python manage.py ldap_sync_users

return

CommandError: Could not connect to LDAP server

from ldap server

openldap | 6225df35 conn=1049 fd=12 ACCEPT from IP=172.25.0.1:47262 (IP=0.0.0.0:389) openldap | 6225df35 conn=1049 op=0 BIND dn="mail=cn\3Dadmin\2Cdc\3Dexample\2Cdc\3Dorg,cn=users,ou=group,dc=example,dc=org" method=128 openldap | 6225df35 conn=1049 op=0 RESULT tag=97 err=49 text= openldap | 6225df3a conn=1049 op=1 UNBIND openldap | 6225df3a conn=1049 fd=12 closed

— Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/239, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABEKCGVHSNQXQYN5XVYPH3U6XMFHANCNFSM5QC4JGKA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>