Ldap-модуль дает сбой при интеграции с Flask - PullRequest
0 голосов
/ 02 июля 2018

Я очень плохо знаком с Flask и программирую в целом, так что, надеюсь, кто-то из вас, ребята и девушки, может дать мне больше разъяснений о том, что на самом деле здесь происходит не так.

Я пытаюсь выполнить очень простую (и небезопасную) LDAP-аутентификацию для внутреннего сервера, но по какой-то причине не могу понять, почему она работает, когда работает как отдельный скрипт, но не работает при интеграции в Flask.

Мой код выглядит так:

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')

А моя LDAP-аутентификация проходит в 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'

Ошибка, возникающая при попытке запустить эту программу:

[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

Но, тем не менее, он прекрасно работает, когда запускается как отдельный скрипт в виртуальной среде.

import auth

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

Запуск вышеуказанного скрипта работает каждый раз.

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

Success!

Я совершенно заблудился в том, что вызывает это, и надеюсь, что смогу получить какое-то руководство. Я потратил целый день на поиски возможного решения, но мне кажется, что я тут попал в кирпичную стену. Спасибо, что нашли время для чтения.

Edit:

Возможное решение состояло в том, что на производственном сервере работала другая версия python-ldap, чем venv, но, похоже, это не так.

Моя среда тестирования и производства находятся на одном сервере и настроены для использования виртуальной среды.

(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"

Однако я попытался установить последнюю версию вне моей виртуальной среды, но проблема осталась прежней.

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

Еще несколько поисков подтверждают, что проблема должна заключаться в интеграции модуля ldap, использование dir (ldap) в virtualenviroment дает правильный вывод с помощью «initialize» и т. Д. Это, однако, ввод, который я получаю, когда делаю то же самое в колба-приложение:

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

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

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Я наконец-то нашел причину проблемы, носкло было близко. Приложение Flask и virtualenviroment различались, но не из-за установленной версии, а из-за прав доступа!

Поскольку flashk-приложение обрабатывается пользователем apache, а пакет python-ldap был установлен с моим собственным пользователем в виртуальной среде, apache не имел доступа к правильному чтению пакета. После настройки прав доступа наконец-то работает.

sudo chown -R apache: apache dir /

0 голосов
/ 02 июля 2018

Проблема в версии пакета python-ldap. Функция initialize была добавлена ​​в последних версиях, до версии 3.0 вам приходилось использовать комбинацию функций open и init.

В вашей среде тестирования установлена ​​последняя версия, и код работает правильно. Но ваша рабочая веб-среда имеет старую версию, которая не может найти функцию initialize, и именно поэтому вы получаете сообщение об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...