flask-ldap3-login
flask-ldap3-login copied to clipboard
MS Active Directory user credential validation failure
User credential validation against MS Active Directory (via NTLM) appears to always fail. From performing an element of troubleshooting, the bind is successful and I can see that the initial search for the user (needing to be validated) succeeds. However, the credential validation always fails with the following error:
No handlers could be found for logger "flask_ldap3_login" AuthenticationResponseStatus.fail
Below is the configuration that is being used in the test script.
from flask_ldap3_login import LDAP3LoginManager
config = dict()
# Setup LDAP Configuration Variables. Change these to your own settings.
# All configuration directives can be found in the documentation.
# Hostname of your LDAP Server
config['LDAP_HOST'] = 'w.x.y.z'
# Base DN of your directory
config['LDAP_BASE_DN'] = 'dc=domain,dc=local'
config['LDAP_USER_DN'] = 'ou=OU2,ou=OU1'
# The RDN attribute for your user schema on LDAP
config['LDAP_USER_RDN_ATTR'] = 'CN'
# The Username to bind to LDAP with
config['LDAP_BIND_USER_DN'] = 'domain.local\\bind-username'
# Declares what ldap attribute corresponds to the username passed to any login method when performing a bind.
config['LDAP_USER_LOGIN_ATTR'] = 'cn'
# Specifies what object filter to apply when searching for users.
config['LDAP_USER_OBJECT_FILTER'] = '(objectclass=user)'
# The Password to bind to LDAP with
config['LDAP_BIND_USER_PASSWORD'] = 'bind-password'
#Specifies what scope to search in when searching for a specific user.
config['LDAP_USER_SEARCH_SCOPE'] = 'SUBTREE'
#Specifies the LDAP bind type to use when binding to LDAP.
config['LDAP_BIND_AUTHENTICATION_TYPE'] = 'NTLM'
# Setup a LDAP3 Login Manager.
ldap_manager = LDAP3LoginManager()
# Init the mamager with the config since we aren't using an app
ldap_manager.init_config(config)
# Check if the credentials are correct
response = ldap_manager.authenticate('test-user', 'test-user-password')
print(response.status)
Hi @bridnic there are numerous reasons why an auth failure might be returned from the library.
I think the best way to debug this from here would be to enable debug logging and see if we can narrow down the path the request is taking inside the library.
You can enable debug logging by setting the level of the library like so:
import logging
logging.getLogger('flask_ldap3_login').setLevel(logging.DEBUG)
...
Let me know what output you get from this when testing with your code.
Hi @nickw444
Here is the output of the debugging:
DEBUG:flask_ldap3_login:Opening connection with bind user 'domain.local\bind-username'
DEBUG:flask_ldap3_login:Successfully bound to LDAP as 'domain.local\bind-username' for search_bind method
DEBUG:flask_ldap3_login:Performing an LDAP Search using filter '(&(objectclass=user)(cn=domain\test-user))', base 'ou=OU2,ou=OU1,dc=domain,dc=local', and scope 'SUBTREE'
DEBUG:flask_ldap3_login:Authentication was not successful for user 'domain.local\test-user'
DEBUG:flask_ldap3_login:Destroying connection at <0x3124310>
AuthenticationResponseStatus.fail
It's probably worth noting that I'm running Python 2.7.5 and so to allow the debug to run correctly, I had to add the line below to the script.
logging.basicConfig()
Hi @bridnic, did you ever manage to solve the issue you were having?
Also, just a side note: after a long internal debate, I have made the difficult decision that I will no longer be actively maintaining this repo. I am now in the process of finding a new maintainer - if this is something that may interest you, you can find more details in the README
Hi @bridnic, did you solve this? My guess is that cn of the user object doesn't have the domain\
-part, so only the LDAP_BIND_USER_DN
should be in that form.
same as me
Same problem here as well. Anyone has been able to figure this out? Interestingly the event logs show NTLM auth successful for the bind.
@bridnic I believe your search filte rlooks wrong. When I use ldp.exe on Windows with (&(objectclass=user)(cn=domain\test-user)) it gives error. It works with (&(objectclass=user)(cn=test-user))