Created
June 10, 2024 12:54
-
-
Save ofurkusi/3f6d57cd5b66a51be032bff6370bd106 to your computer and use it in GitHub Desktop.
Using the ldap3 package to authenticate against an Active Directory service in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from ldap3 import Server, Connection, NTLM, SUBTREE | |
# Hostname of your Active Directory (AD, LDAP) Server | |
LDAP_HOST = 'ad.example.com' | |
LDAP_PORT = 636 | |
LDAP_USE_SSL = True | |
# The base DN of your LDAP directory (DNS of the domain) | |
LDAP_BASE_DN = 'dc=example,dc=com' | |
# The NetBIOS name of the domain, used for NTLM authentication. | |
LDAP_BIND_NTLM_DOMAIN = 'EXAMPLE-DOMAIN' | |
LDAP_BIND_DIRECT_PREFIX = LDAP_BIND_NTLM_DOMAIN+'\\' | |
# Set search base for users. This is the location of user accounts in the | |
# LDAP directory. | |
LDAP_USER_DN = 'ou=Staff,ou=Users' | |
LDAP_SEARCH_BASE = "{},{}".format(LDAP_USER_DN, LDAP_BASE_DN) | |
server = Server(LDAP_HOST, port=LDAP_PORT, use_ssl=LDAP_USE_SSL) | |
# Establishing a connection to the AD server, authenticating with the provided credentials | |
username = "username" | |
password = "password" | |
conn = Connection(server, user=LDAP_BIND_DIRECT_PREFIX+username, password=password, authentication=NTLM) | |
user_pass_valid = conn.bind() | |
if not user_pass_valid: | |
print("Unauthorized: Invalid credentials.") | |
# Checking membership of a specific access group | |
# How objects are identified in the directory. These are defaults for AD. | |
# NOTE: `sAMAccountName` contains the user id used for NTLM login in AD. | |
LDAP_USER_LOGIN_ATTR = 'sAMAccountName' | |
# NOTE: User accounts typically are instances of multiple objectClasses (i.e. | |
# inherit attributes from multiple objectClasses), e.g. `user` or | |
# `person`. `user` is the however the base class for all users in AD. | |
LDAP_USER_OBJECT_FILTER = 'objectClass=user' | |
# NOTE: The `memberOf` attribute of a user contains a list of all groups of | |
# which the user is a member. | |
LDAP_GET_USER_ATTRIBUTES = 'memberOf' | |
# The DN of the group to check for membership of. | |
LDAP_REQUIRED_MEMBERSHIP = "cn=Accounting,ou=Groups,dc=example,dc=com" | |
# NOTE: If using `flask_ldap3_login` pass `SUBTREE` as a string. | |
LDAP_USER_SEARCH_SCOPE = SUBTREE | |
access = conn.search( | |
search_base=LDAP_SEARCH_BASE, | |
search_filter=f'(&({LDAP_USER_OBJECT_FILTER})({LDAP_GET_USER_ATTRIBUTES}={LDAP_REQUIRED_MEMBERSHIP})({LDAP_USER_LOGIN_ATTR}={username}))', | |
search_scope=LDAP_USER_SEARCH_SCOPE | |
) | |
# Close connection to the AD server. | |
conn.unbind() | |
if not access: | |
print("Forbidden: Not part of the correct access group.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment