top of page
5.15 Technologies

LDAP and Django: Securing Your Application Within a Windows Domain

Authentication is a fundamental aspect of any web application. It's critical to ensure that only authorized users have access to sensitive information. While Django comes with a robust authentication system out of the box, it may not be the best fit for your organization's needs.


If you're looking for a more centralized and secure way to manage user authentication, LDAP may be the answer. LDAP is a widely used protocol for accessing and maintaining information distributed across a network. Plus, it can be integrated with Django to provide centralized authentication and authorization.


In this blog, we will explore how to use LDAP authentication with Django. Note: We will not be covering how to run a Django application in a Windows domain. Instead, it will be assumed that the Django application is already deployed, and we are updating the application to integrate with the Windows domain for LDAP authentication.


What are the Benefits of Using LDAP Authentication?

The benefits of LDAP with Django are very similar to the common benefits of using LDAP for authentication and user management. Below are a few of the top benefits that truly shine through when using LDAP with Django.

  • Centralized user management: LDAP enables organizations to manage user accounts centrally. Which helps in maintaining uniformity across different systems and applications.

  • Increased Security: LDAP authentication adds an extra layer of security. Requiring users to authenticate their credentials before accessing applications or systems.

  • Reduced Administrative Efforts: LDAP authentication reduces the administrative burden of creating and managing user accounts for different systems and applications separately.

  • Improved User Experience: LDAP authentication allows users to access multiple systems and applications. Simply by using a single set of login credentials.

Setting Up Django with LDAP Authentication

There are several setting changes that are needed to get LDAP authentication working with Django. The LDAP authentication configuration that we'll cover will be built on top of our Django Sample Application. The build out for the LDAP authentication will be in its own branch that will build on top of the swagger branch located below.

For our purposes, we will be looking at authentication with the Django API. This setup applies to authentication with a login form as well.


The first thing we are going to look at is the requirements.txt as there is a new Python library that must be installed for LDAP authentication to properly work. The new Python library is called django-python3-ldap. This will allow us to define LDAP groups that can be used for authentication. Making it easier to manage access to the application. The new requirements.txt file looks like the following:

Django~=3.2.16
python-dateutil~=2.8.2
urllib3~=1.26.12
requests~=2.28.1
djangorestframework~=3.14.0
drf-yasg~=1.21.4
django-python3-ldap~=0.15.4

The next section that needs updating is the settings.py file. This file will get the new configurations to implement some of the new features that will be used for authentication. The first variable we will be updating is the INSTALLED_APPS variable. The new app that needs to be added is django_python3_ldap. The new INSTALLED_APPS variable should look like the following:

INSTALLED_APPS = [
    'app',
    'api',
    'rest_framework',
    'personnel',
    'drf_yasg',
    'django_python3_ldap', 
    … TRUNCATED
]

After the INSTALLED_APPS configuration, you need to configure the AUTHENTICATION_BACKENDS variable. As seen below. Including only the LDAPBackend to ensure only LDAP authentication is used for the application.

AUTHENTICATION_BACKENDS = [
    'django_python3_ldap.auth.LDAPBackend',
]

Lastly, the LDAP settings need to be configured. There are three environment variables that need to be configured to work properly with your domain. For this demonstration, a .env file is being used along with the python-dotenv Python library to load the environment variables. As each environment will be different. The variables would be configured in the below examples based on a domain name of test.com:

  • DOMAIN_NAME_FQDN=test.com

  • NETBIOS_DOMAIN_NAME=TEST

  • DOMAIN_SEARCH_BASE='DC=test,DC=com'

LOGIN_REDIRECT_URL = "/"
LDAP_AUTH_URL = os.environ.get('DOMAIN_NAME_FQDN')

LDAP_AUTH_FORMAT_USERNAME = 'django_python3_ldap.utils.format_username_active_directory'
LDAP_AUTH_USE_TLS = True
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = os.environ.get('NETBIOS_DOMAIN_NAME')

LDAP_AUTH_SEARCH_BASE = os.environ.get('DOMAIN_SEARCH_BASE')

LDAP_AUTH_OBJECT_CLASS = 'user'
LDAP_AUTH_FORMAT_SEARCH_FILTERS = 'demoapp.searchfilter.group_search_filter'
LDAP_AUTH_USER_FIELDS = {
    'username': 'sAMAccountName',
    'first_name': 'givenName',
    'last_name': 'sn',
    'email': 'mail',
}

After all configurations are made, the last thing to do is create the search filter. This is defined in the LDAP_AUTH_FORMAT_SEARCH_FILTERS variable from above. In this configuration, the file searchfilter.py lives in the “demoapp” app, which is the base folder for our Django application. However, you can put the file in any app. Just as long as you update the LDAP_AUTH_FORMAT_SEARCH_FILTERS variable accordingly. The function that will be used as the search filter will be called group_search_filter. Below is the configuration of that search filter.

def group_search_filter(ldap_fields):
    search_filters = format_search_filters(ldap_fields)
    search_filters.append(f"(memberOf=CN=Django_Users,OU=Groups,{os.environ.get('DOMAIN_SEARCH_BASE')})")
    
    return search_filters

The last file that needs to be updated to enforce authentication with the Django API is to update all the API views that we want to enforce authentication with. There are two new imports required.

from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated

Additionally, there are two variables that need to be defined under each APIView class to ensure all endpoints under that APIView enforce authentication. As seen below.

class Personnel(APIView):
    authentication_classes = [BasicAuthentication]
    permission_classes = [IsAuthenticated]


Testing LDAP Authentication with the API

Now that we have our Django application fully configured with LDAP authentication, we can start to test it. However, we need to make sure that the user group defined in the search filter is created and has a user defined. In this setup, we are using an Active Directory group called “Django_Users” that exists in the “Groups” OU under our base Domain. This can be seen in the screenshot below. We've also added a user called “test_user” to the group for testing.

For testing the API, we will be using the swagger page located at http://{IP}:8000/api/swagger. Now, if we try to make an API request that isn’t authenticated, we are prompted with a login box for a username and password. As seen below.

If we don’t provide any credentials, this will be our response:

However, if we log in using the Authorize button at the top of the Swagger page and then try the request, we have successfully validated that the user group defined in Django is being used as our authentication method for our Django application. Resulting in a successful output of data.




Conclusion

LDAP authentication offers a powerful and secure way to manage user authentication in Django. By integrating LDAP with your Django application, you can centralize your user management. Taking advantage of LDAP's security features. We've covered the key steps to configure LDAP authentication for your Django application. We've also explored authenticating with the Django API. Demonstrating what a successful and unsuccessful request looks like.


With LDAP authentication in place, you can ensure that only authorized users have access to sensitive information. Maintaining a consistent user experience across your organization's systems. It can also simplify user management by centralizing user authentication and authorization. Integrating LDAP with Django offers organizations a valuable tool that encompasses security, simplicity, and centralization. With that being said, are you ready to integrate LDAP in your Django application?


Thank you for taking the time to review this article and feel free to contact us if your project needs more advanced capabilities.


Comments


bottom of page