Using a django application as a LDAP server with django-ldap-server

django-ldap-server allow other applications to authenticate against Django accounts using LDAP protocols.

It’s a django application packaged as a docker container. It need access to the database used by your django application and share your user model.

Source

https://bitbucket.org/xael/django-ldap-server

Run

docker run --rm \
  -e DATABASE_URL=postgres://user:password@postgres/database \
  -e SLAPD_DOMAIN="dc=example,dc=company,dc=org" \
  -e SLAPD_PASSWORD=adminpassword \
  --link dev_postgres_1:postgres \
  --network dev_default \
  -p 1389:389  \
  xael/django-ldap-server

Environment variables are

Mandatory

  • DATABASES_URL: url of database to connect to
  • SLAPD_PASSWORD: admin password for LDAP
  • SLAPD_DOMAIN: Ldap domain (dc=example, dc=company, dc=org)

Optionnal

  • LDAP_PORT: Listening port (default :  398)
  • AUTH_USER_MODEL: Django model used for user (default :  “accounts.User”)
  • DJANGO_SETTINGS_MODULE: Setting files (default :  “ldap_server.settings”)

You can override user model in docker container by remplacing /django/accounts/models.py:

docker run --rm -e DATABASE_URL=postgres://user:password@postgres/database \
  -e SLAPD_PASSWORD=adminpassword \
  -v /path/custom_user_model.py:/django/accounts/models.py \
  -p 1389:389  xael/django-ldap-server
Default user model
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import ugettext_lazy as _

from django.contrib.auth.models import UserManager


class User(AbstractBaseUser, PermissionsMixin):
    class Meta:
        managed = False

    objects = UserManager()
    USERNAME_FIELD = 'email'

    email = models.EmailField(unique=True)
    first_name = models.CharField(_('First name'), max_length=300)
    last_name = models.CharField(_('Last name'), max_length=300)

    is_staff = models.BooleanField(_('staff status'),
                                   default=False,
                                   help_text=_('admin ?'))
    is_active = models.BooleanField(_('active'),
                                    default=True,
                                    help_text=_('Utilisateur actif ?'))

Use with docker-compose

ldap:
  image: xael/django-ldap-server:latest
  links:
    - postgres
  environment:
    DATABASE_URL: postgres://user:password@postgres/database
    DJANGO_SETTINGS_MODULE: "ldap_server.settings"
    SLAPD_DOMAIN: dc=example,dc=company,dc=org
    SLAPD_PASSWORD: adminpassword

If you want to connect from an external server, you can use a ssh tunnel :

ssh:
  image: polandj/alpine-ssh
  ports:
    - "2222:22"
  links:
    - ldap
  environment:
      AUTHORIZED_KEYS: ssh-rsa AAAA[...]rbE7n user@computer

And connect :

ssh -L 1389:ldap:389 -p 2222 root@server