Объект «AnonymousUserMixin» не имеет ошибки атрибута «роли» на веб-сервере Airflow при использовании LDAP с Flask-AppBuilder RBAC

Я пытаюсь интегрировать аутентификацию Airflow Webserver с RBAC Flask-AppBuilder, доступным в Airflow 1.10.0, но независимо от настроек конфигурации, которые я пробую, я получаю AttributeError: 'AnonymousUserMixin' object has no attribute 'roles'.

Ранее я получил серверную часть аутентификации Airflow LDAP для работы с сервером LDAP Microsoft AD моей организации, но я не могу правильно настроить параметры конфигурации, чтобы он мог работать с FAB RBAC. В документации Airflow и FAB очень мало говорится о LDAP или его устранении.

В ${AIRFLOW_HOME}/webserver_config.py файле у меня

# The authentication type
AUTH_TYPE = AUTH_LDAP

AUTH_ROLE_PUBLIC = "Public"
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Public"

AUTH_LDAP_SERVER = "ldaps://ldaps.myorg.org:636"
AUTH_LDAP_BIND_USER = "CN=myuser,OU=Service Accounts,DC=myorg,DC=org"
AUTH_LDAP_BIND_PASSWORD = "relevant_password"
AUTH_LDAP_SEARCH = "DC=myorg,DC=org"
AUTH_LDAP_UID_FIELD = "sAMAccountName"
# AUTH_LDAP_ALLOW_SELF_SIGNED = True
AUTH_LDAP_USE_TLS = False
AUTH_LDAP_APPEND_DOMAIN = "myorg.org"
AUTH_ROLE_ADMIN = "Admin"

И в {AIRFLOW_HOME}/airflow.cfg у меня

[webserver]
authenticate = True
rbac = True

Я уже обновил серверную базу данных Postgres, чтобы в ней было ab_ таблиц.

Когда я развертываю все через Docker Swarm и перехожу на соответствующий URL-адрес веб-сервера, я просто получаю указанную выше ошибку с трассировкой стека. Он никогда не дает мне возможности войти в систему (и я попытался очистить файл cookie), поэтому я не понимаю, как заставить его позволить «анонимному» пользователю даже попытаться аутентифицироваться с помощью LDAP AD.

Проблема

  • webserver_config.py настройки LDAP?
  • кавычки вокруг этих настроек?
  • airflow.cfg настройки?
  • что-то о сервере LDAP моей организации?
  • что-то другое?

Пожалуйста, дайте мне знать, если я упустил какую-либо информацию. Спасибо!


person Soren B    schedule 10.01.2019    source источник


Ответы (2)


Что ж, к счастью, я понял это и могу ответить на свой вопрос, первый вопрос, на который был дан ответ на ТАК.

Отчасти причина в том, что FAB использует пакет python-ldap для обработка ошибок, но есть также пакеты ldap3 и ldap, которые, если вы устанавливаете их в определенном порядке, могут помешать использованию python-ldap.

Я также обнаружил, что python-ldap имеет определенные требования к сборке.

Вдобавок я обнаружил, что в FAB есть еще один параметр LDAP, AUTH_LDAP_SEARCH_FILTER, который позволяет фильтровать возможных пользователей по определенной группе, что я и хотел, но не упоминается в документации; Я нашел его в репозитории пакетов на GitHub.

Вот мой webserver_config.py файл, который мне подходит:

# -*- coding: utf-8 -*-

import os
from airflow import configuration as conf
from flask_appbuilder.security.manager import AUTH_LDAP
basedir = os.path.abspath(os.path.dirname(__file__))

# The SQLAlchemy connection string.
SQLALCHEMY_DATABASE_URI = conf.get('core', 'SQL_ALCHEMY_CONN')

# Flask-WTF flag for CSRF
CSRF_ENABLED = True

# ------------------------------------------------------------------------------
# AUTHENTICATION CONFIG
# ------------------------------------------------------------------------------
# For details on how to set up each of the following authentications, see
# http://flask-appbuilder.readthedocs.io/en/latest/security.html# authentication-methods

# The authentication type
AUTH_TYPE = AUTH_LDAP

AUTH_ROLE_PUBLIC = "Public"
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Viewer"

AUTH_LDAP_SERVER = "ldaps://ldaps.myorg.org:636"
AUTH_LDAP_BIND_USER = "CN=myuser,OU=Service Accounts,DC=myorg,DC=org"
AUTH_LDAP_BIND_PASSWORD = "relevant_password"
AUTH_LDAP_SEARCH = "DC=myorg,DC=org"  # same as BASEDN
AUTH_LDAP_SEARCH_FILTER = "(memberOf=CN=My Team,OU=My Group,DC=myorg,DC=org)"
AUTH_LDAP_UID_FIELD = AUTH_LDAP_UID_FIELD = "sAMAccountName"
AUTH_LDAP_ALLOW_SELF_SIGNED = True
AUTH_LDAP_USE_TLS = False
AUTH_LDAP_TLS_DEMAND = True
AUTH_ROLE_ADMIN = "Admin"

Я установил AUTH_USER_REGISTRATION_ROLE на Viewer, потому что по умолчанию Public не имеет связанных с ним разрешений, поэтому, если кто-то в AD входит в систему и его роль по умолчанию установлена ​​на Public, они не смогут ничего делать, пока администратор не изменит их роль.

Я узнал от ИТ-отдела в своей организации, что контроллер домена LDAP-сервера обрабатывает TLS, поэтому я думаю, что поэтому я могу установить AUTH_LDAP_ALLOW_SELF_SIGNED на True, тогда как у меня нет сертификата TLS в контейнерах Docker, чтобы указать Airflow, чтобы чтобы установить AUTH_LDAP_USE_TLS в True.

person Soren B    schedule 19.01.2019

AnonymousUserMixin - это класс миксина, определенный в Flask-Login пакете python. Вероятно, вы столкнулись с проблемой, когда кодовый путь предполагает, что пользователь вошел в систему. Вы можете изменить этот кодовый путь следующим образом:

if flask_login.current_user.is_authenticated():
    *code*

Возможно, вы захотите добавить собственный класс в качестве своего анонимного пользовательского класса в код конфигурации / настройки приложения Flask.

class MyCustomAnonymousUser(flask_login.AnonymousUserMixin):
    def __init__(self):
        self.roles = []

flask_app = Flask(...)  # some flask app being initialized
flask_app.login_manager.anonymous_user = MyCustomAnonymousUser

Однако также возможно, что код, который выдает эту ошибку, ожидает настройки Flask-Security. Заглянем под капот того, что делает Flask-Security:

from flask.ext.login import AnonymousUserMixin, UserMixin as BaseUserMixin, \
LoginManager, current_user

...


class AnonymousUser(AnonymousUserMixin):
    """AnonymousUser definition"""

    def __init__(self):
        self.roles = ImmutableList()

    def has_role(self, *args):
        """Returns `False`"""
        return False

Чтобы настроить Flask-Security для своего приложения, ознакомьтесь с кратким руководством по их документации: https://pythonhosted.org/Flask-Security/quickstart.html

person Bobby    schedule 10.01.2019
comment
Я думаю, что понимаю использование AnonymousUserMixin, но не думаю, что мне нужно редактировать какой-либо код, связанный с Flask, в Airflow, иначе мне придется делать это каждый раз, когда появляется новая версия. Конечно, я не могу быть первым человеком в мире, который попытается использовать LDAP для аутентификации с помощью FAB ...? - person Soren B; 10.01.2019