0

I am currently working on my webapp. As of now, I can login with the username (sAMAccountName) but I want to login with the e-mail-adress. I looked up some backends, but none of them could help me.

Here are my setting.py

AUTH_LDAP_SERVER_URI = "ldap://192.168.4.123"
AUTH_LDAP_BIND_DN = "username"
AUTH_LDAP_BIND_PASSWORD = "password"
AUTH_LDAP_CONNECTION_OPTIONS = {
    ldap.OPT_DEBUG_LEVEL: 1,
    ldap.OPT_REFERRALS: 0
}

AUTH_LDAP_USER_SEARCH = LDAPSearch("DC=domain,DC=com", ldap.SCOPE_SUBTREE, "(sAMAccountName=%(user)s)")
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("DC=domain,DC=com", ldap.SCOPE_SUBTREE, "(objectClass=group)")
AUTH_LDAP_GROUP_TYPE = NestedActiveDirectoryGroupType()

AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
    "dn": "distinguishedName",
}

AUTH_LDAP_USER_FLAGS_BY_GROUP = {
    "is_active": "CN=users,cn=users,DC=domain,DC=com",
    "is_staff": "CN=users,cn=users,DC=domain,DC=com",
    "is_superuser": "CN=users,cn=users,DC=domain,DC=com"
}

AUTH_LDAP_ALWAYS_UPDATE_USER = True

LDAP_AUTH_OBJECT_CLASS = "inetOrgPerson"

AUTH_LDAP_FIND_GROUP_PERMS = True

AUTH_LDAP_CACHE_GROUPS = True
AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600

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

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'stream_to_console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler'
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        'django_auth_ldap': {
            'handlers': ['stream_to_console'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

Maybe you have a good backend or I am missing something. I also tried:

AUTH_LDAP_USER_SEARCH = LDAPSearch("DC=sbvg,DC=ch", ldap.SCOPE_SUBTREE, "(mail=%(user)s)")

but then it creates a user with the username user@domain.com, which is also wrong.

halfer
  • 19,824
  • 17
  • 99
  • 186
GeniusBehind
  • 89
  • 12

1 Answers1

0

User model is already built in Django to use email as username you need to do some changes in that model. use below code to customize your username and paste it in models.py.

from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)

class User(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    active = models.BooleanField(default=True)
    staff = models.BooleanField(default=False) # a admin user; non super-user
    admin = models.BooleanField(default=False) # a superuser
    objects = UserManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [] # Email & Password are required by default.

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):              # __unicode__ on Python 2
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        return self.staff

    @property
    def is_admin(self):
        "Is the user a admin member?"
        return self.admin

    @property
    def is_active(self):
        "Is the user active?"
        return self.active

Django has built-in methods for the User Manager. We have to customize them in order to make our custom user model work correctly. below code will also be written in models.py

class UserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, email, password):
        user = self.create_user(
            email,
            password=password,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        user = self.create_user(
            email,
            password=password,
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user

use both commands: python manage.py makemigrations [app name] python manage.py migrate

Now open up settings.py: AUTH_USER_MODEL = 'app.User'

Run again: python manage.py makemigrations [app name] python manage.py migrate

Now create a new user with email and try to login. it seems too complicated but I hope it will work.

for more see this video.

bSr
  • 1,410
  • 3
  • 16
  • 30
  • first of all thank you for this. But does this also work for ldap users? It looks like its for the ModelBackend. – GeniusBehind Mar 06 '18 at 12:25
  • did u see this one: https://stackoverflow.com/questions/21458071/django-auth-ldap-with-custom-user-model – bSr Mar 06 '18 at 12:36