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