etianen / django-python3-ldap

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

Login not working when running inside Docker container #150

Closed TheOrangePuff closed 5 years ago

TheOrangePuff commented 5 years ago

This is a weird issue and I can't work out exactly what's going on...

I'm trying to deploy my Django app to Docker and when testing on my local machine everything works as intended. However when I deployed the containers to Docker (running on Ubuntu LTS) the LDAP login no longer works (logging in as the default admin account works fine).

I can run ldap_sync_users and that works perfectly it's just logging in that doesn't seem to work.

Any ideas as to how I could fix/troubleshoot this? Thanks!

etianen commented 5 years ago

No idea, I'm afraid. Docker itself should not make a difference.

Try turning on logging, and see what messages you get: https://github.com/etianen/django-python3-ldap#cant-get-authentication-to-work

On Wed, 9 Jan 2019 at 01:24, Daniel van der Ploeg notifications@github.com wrote:

This is a weird issue and I can't work out exactly what's going on...

I'm trying to deploy my Django app to Docker and when testing on my local machine everything works as intended. However when I deployed the containers to Docker (running on Ubuntu LTS) the LDAP login no longer works (logging in as the default admin account works fine).

I can run ldap_sync_users and that works perfectly it's just logging in that doesn't seem to work.

Any ideas as to how I could fix/troubleshoot this? Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/150, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCCQaj08QxKq_Ri16mEd4b_wquR7Oks5vBUTbgaJpZM4Z2lcO .

TheOrangePuff commented 5 years ago

Unfortunately I'm not getting any output from enabling logging.

On my local machine I get: LDAP connect succeeded LDAP user lookup succeeded

So it's clearly working there.

etianen commented 5 years ago

And what do the logs say in the docker deployment?

On Wed, 9 Jan 2019 at 23:00, Daniel van der Ploeg notifications@github.com wrote:

Unfortunately I'm not getting any output from enabling logging.

On my local machine I get: LDAP connect succeeded LDAP user lookup succeeded

So it's clearly working there.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/150#issuecomment-452901890, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCPxyudSvyui0ohvyUFF52pIviSiIks5vBnSKgaJpZM4Z2lcO .

TheOrangePuff commented 5 years ago
[10/Jan/2019 23:31:57] "POST /login/ HTTP/1.0" 200 2772
[10/Jan/2019 23:32:03] "POST /login/ HTTP/1.0" 200 2772
[10/Jan/2019 23:32:11] "POST /login/ HTTP/1.0" 200 2772

Just this. The logs don't mention anything about LDAP which is confusing...

TheOrangePuff commented 5 years ago

Here's my config file

import os
import django_pyodbc
import django_python3_ldap

from CarnivalScoringSystem import secretKey, dbSettings, adSettings

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = secretKey.getSecretKey()

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

# Redirect to home URL after login (Default redirects to /accounts/profile/)
LOGIN_REDIRECT_URL = '/home/'
LOGIN_URL = ('login')

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = [
    'home.apps.HomeConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_python3_ldap',
    'django_bootstrap_breadcrumbs',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'home.middleware.redirects',
]

ROOT_URLCONF = 'CarnivalScoringSystem.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['./templates',],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'CarnivalScoringSystem.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'NAME': dbSettings.getName(),
        'ENGINE': 'sql_server.pyodbc',
        'HOST': dbSettings.getHost(),
        'USER': dbSettings.getUserName(),
        'PORT': 1433,
        'PASSWORD': dbSettings.getPassword(),
        'OPTIONS': {
            'driver': 'FreeTDS',
            'host_is_server': True,
            'extra_params': 'TDS_VERSION=7.0',
        }
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/'),]
STATIC_ROOT = '/staticfiles'

AUTHENTICATION_BACKEND = ("django_python3_ldap.auth.LDAPBackend", "django.contrib.auth.backends.ModelBackend",)

# The URL of the LDAP server.
LDAP_AUTH_URL = adSettings.getAuthURL()

# Initiate TLS on connection.
LDAP_AUTH_USE_TLS = False

# The LDAP search base for looking up users.
LDAP_AUTH_SEARCH_BASE = adSettings.getLDAPSearchBase()

# The LDAP class that represents a user.
LDAP_AUTH_OBJECT_CLASS = "organizationalPerson"

AUTH_LDAP_FIND_GROUP_PERMS = True

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

# 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 and a dict of {ldap_field_name: [value]},
# 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_active_directory"
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = adSettings.getADDomain()

# 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 = adSettings.getUserName()
LDAP_AUTH_CONNECTION_PASSWORD = adSettings.getPassword()

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

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    'file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': '/app/debug.log',
        },
    },
    "loggers": {
        "django_python3_ldap": {
            "handlers": ["console", "file"],
            "level": "INFO",
        },
    },
}
TheOrangePuff commented 5 years ago

Here's the output from when I run ldap_sync_users in the docker deployment

LDAP user lookup succeeded
Synced user01
LDAP user lookup succeeded
Synced user02
etianen commented 5 years ago

Weird, issue, but it feels like something to do with your deployment, rather than django-python3-ldap.

I'd suggest patching in a load of print() statements into bits of django-python3-ldap and django.contrib.auth, and try to figure out what is going on. If it's something that needs fixing in django-python3-ldap, I'll happily take a PR.

On Fri, 11 Jan 2019 at 00:01, Daniel van der Ploeg notifications@github.com wrote:

Here's the output from when I run ldap_sync_users in the docker deployment

LDAP user lookup succeeded Synced user01 LDAP user lookup succeeded Synced user02

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/etianen/django-python3-ldap/issues/150#issuecomment-453309597, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJFCJV5f0cdLqVDNLSrtRKFwglKqYB2ks5vB9Q_gaJpZM4Z2lcO .

TheOrangePuff commented 5 years ago

Yeah I'll have a go with it next week. I think you're right though but I'll let you know if I find a solution.

ukasiu commented 5 years ago

Seems I'm also affected. Sync works, login doesn't. AWS Beanstalk + Daphhne EDIT: nvm, seems that removing LDAP_AUTH_USE_TLS helped.

TheOrangePuff commented 5 years ago

So I had another crack at this. Started everything again from the ground up and it seems to be working? Unfortunately don't know how I fixed it so I won't be much use to anyone else who has this issue.

I'll close the issue as it's no longer a problem.