Skip to content

Instantly share code, notes, and snippets.

@ofurkusi
Created June 10, 2024 12:54
Show Gist options
  • Save ofurkusi/3f6d57cd5b66a51be032bff6370bd106 to your computer and use it in GitHub Desktop.
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
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