pythondjangodjango-admindjango-authenticationdjango-auth-ldap

Using Django Admin Page to Add Users with other AUTHENTICATION_BACKEND


I'm using django_auth_ldap to authenticate users for a Django project against a large corporate ActiveDirectory system that's not organized in a useful way (and I don't have the ability to change it). As such, I have to add users individually so that I don't end up with any user who can authenticate against LDAP being able to sign into the system. It's possible to add LDAP users on the command line using

from django_auth_ldap.backend import LDAPBackend

user = LDAPBackend().populate_user('alice')

but I can't use the admin page to do the same thing (adding user forces me to enter a password rather than just having the account inherit the LDAP credentials that already exist.)

It would appear that there isn't an easy/clever way to accomplish this without having to write a django admin page (though if I'm wrong on this, please correct me). How do I add a simple admin page that just creates a user without setting the password or anything else?

I understand that the basic mechanics basically involve doing something like:

from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

UserAdmin.add_form_template = ('addLDAPuser.html')

admin.site.unregister(User)
admin.site.register(User,UserAdmin)

but I'm still fuzzy on making a template and processing logic so that I don't just end up with a bunch of user accounts that will successfully authenticate against django.contrib.auth.backends.ModelBackend with empty passwords. (Obviously, I could just remove django.contrib.auth.backends.ModelBackend from the AUTHENTICATION_BACKENDS in settings.py, but that also removes my ability to have a local admin account separate from LDAP.)


Solution

  • What you could try is extending the standard user model and overriding its save() method. Make sure you read up on the consequences of overriding the save method here. Such a model could look like this:

    from django.db import models
    from django.contrib.auth.models import User
    
    # Create your models here.
    
    class LDAPUser(models.Model):
            user = models.OneToOneField(User, editable=False)
            username = models.CharField(max_length=32, unique=True)
    
            def save(self, *args, **kwargs):
                    self.user, _ = User.objects.get_or_create(username=self.username)
                    self.user.save()
                    '''
                    Do custom saving here:
                    from django_auth_ldap.backend import LDAPBackend
    
                    user = LDAPBackend().populate_user('alice')
                    '''
                    super(LDAPUser, self).save(*args, **kwargs)
    
            def __unicode__(self):
                    return self.username
    

    By not providing the user with a password, they cannot log in using the password field. Hopefully this means your LDAP backend will be the only way of authenticating for the LDAP users..