Ldap-module fails when intregrating with Flask


Ldap-module fails when intregrating with Flask



I'm very new to Flask and coding in general so hopefully someone of you guys & girls can give me some more clarification on what's actually going wrong here.



I'm trying to do a very simple (and unsecure) LDAP-authentication towards an internal server, but for some reason I can't for the life of me figure out why it works when running as a standalone script but breaks when integrated in Flask.



My code looks like this:



main.py


from flask import Flask, render_template, request, redirect, session

app = Flask(__name__)
app.config.from_object('config.BaseConfig')

import auth

@app.route('/login', methods=['GET', 'POST'])
def login_page():

if request.method == 'POST':

username = request.form['username']
password = request.form['password']

results = auth.authenticate(username,password)
if results == 'OK':
session['username'] = username
session['logged_in'] = True
return redirect(url_for('home_page'))
else:
error = 'Invalid Credentials. Please try again.'
return render_template('login.html', error=error)

return render_template('login.html')



And my LDAP-Authentication is handeld in auth.py:



auth.py


import ldap

def authenticate(username, password):
LDAP_SERVER = 'ldap://ldap.server'
LDAP_USERNAME = 'LDAP%s' % username
LDAP_PASSWORD = password
try:
ldap_client = ldap.initialize(LDAP_SERVER)
ldap_client.set_option(ldap.OPT_REFERRALS,0)
ldap_client.simple_bind_s(LDAP_USERNAME, LDAP_PASSWORD)
except:
ldap_client.unbind()
return 'PASSWORD_ERROR'
ldap_client.unbind()
return 'OK'



The error I get when trying to run this program is:


[Mon Jul 02 19:49:35.018001 2018] [wsgi:error] [pid 20574] [client 10.79.0.38:63620] File "/var/www/html/website/auth.py", line 11, in authenticate, referer: http://.../login
[Mon Jul 02 19:49:35.018010 2018] [wsgi:error] [pid 20574] [client 10.79.0.38:63620] ldap_client = ldap.initialize(LDAP_SERVER), referer: http://.../login
[Mon Jul 02 19:49:35.018029 2018] [wsgi:error] [pid 20574] [client 10.79.0.38:63620] AttributeError: 'module' object has no attribute 'initialize', referer: http://.../login
[Mon Jul 02 19:49:35.019141 2018] [wsgi:error] [pid 20574] [client 10.79.0.38:63620] ldap_client.unbind(), referer: http://.../login
[Mon Jul 02 19:49:35.019155 2018] [wsgi:error] [pid 20574] [client 10.79.0.38:63620] UnboundLocalError: local variable 'ldap_client' referenced before assignment, referer: http://.../login



But it does however work just fine when running it as a standalone script in the virtual enviroment.


import auth

results = auth.authenticate('someuser','somepassword')
if results == 'OK':
print("Success!")
else:
print(results)



Running the above script works everytime.


(flaskenv) [webserver website]$ python test.py

Success!



I'm completely lost on what is causing this and hope I can get some guidance. I've spent the entire day googling for a possible solution but it feels like ive hit a brick wall here. Thanks for taking the time reading.



Edit:



A possible solution was that the production server was running another version of python-ldap than the venv, but this seems not to be the case.



My testing enviroment and production is on the same server and is set up to use the virtual enviroment.


(flaskenv) [webserver website]$ pip freeze | grep ldap
python-ldap==3.1.0

WSGIPythonHome "/var/www/html/website/flaskenv/"
WSGIPythonPath "/var/www/html/website/flaskenv/lib/python3.4/site-packages"



I did however try to install the latest version outside my virtual enviroment but the problem remains the same.


[webserver ~]$ pip3 freeze
python-ldap==3.1.0



Some more searching confirms that the issue must be with the integrating the ldap module, using dir(ldap) in the virtualenviroment gives the correct output with "initialize" etc. This is however the input I get when doing the same in the flask-app:


@app.route('/form')
def form_page():
debug = dir(ldap)
return str(debug)

['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']




2 Answers
2



The problem is in the version of the python-ldap package. The initialize function was added in the latest versions, before version 3.0 you had to use a combination of the open and init functions.


python-ldap


initialize


open


init



Your testing environment has the latest version, and the code works correct. But your production web environment has the old version that can't find the initialize function, and that is why you get the error.


initialize





Thank you! It dosen't however seem to be the case from what I can tell, I updated my post showing a bit more in detail. The production web is/should be running in the same enviroment that i'm testing in.
– smoegendev
Jul 3 at 2:10



I finally found what was causing the issue, nosklo was close. The Flask-app and the virtualenviroment differed, but not due to installed version - but due to access rights!



As the flask-app is handled by the user apache and the python-ldap package was installed with my own user in the virtual enviroment apache didn't have access to reading the package correctly. After adjusting accessrights it finally works.



sudo chown -R apache:apache dir/






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages