我正在使用Flask安全性对用户进行身份验证。我已确保身份验证可与http_auth_required装饰器一起正常使用-已针对用户存储(在本例中为SQLAlchemyUserDatastore)验证了用户,一切都很好。

我现在想使用自己的身份验证方法(我将使用自定义的LDAP验证系统),同时仍然利用Flask-Security给我的东西(例如current_user)。我编写了一个自定义装饰器,如下所示:

def authenticate_with_ldap(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if not request.authorization:
            return unauthorized_user_handler()
        user = user_datastore.get_user(request.authorization.username)
        if not user or not authenticate_with_ldap(user.email, user.password):
            return unauthorized_user_handler()
        return func(*args, **kwargs)
    return wrapper


但是,当我查看http_auth_required装饰器时,我看到它使用了一个名为_check_http_auth的私有函数,该函数执行的某些工作如果不访问私有成员就无法自己完成,例如将用户设置为顶部。请求上下文堆栈和发送信号。代码如下:

def _check_http_auth():
    auth = request.authorization or BasicAuth(username=None, password=None)
    user = _security.datastore.find_user(email=auth.username)

    if user and utils.verify_and_update_password(auth.password, user):
        _security.datastore.commit()
        app = current_app._get_current_object()
        _request_ctx_stack.top.user = user
        identity_changed.send(app, identity=Identity(user.id))
        return True

    return False


所以我的问题是:拥有自定义身份验证方法的正确方法是什么,同时仍充分利用Flask-Security?

最佳答案

您可以使用快速的猴子补丁来完成此操作。这并不理想,但是我不确定在Flask-Security团队以更优雅的方式编写来解决此问题之前您还能做什么。

import flask_security

def verify_and_update_password_custom(password, user):
    return user.verify_password(password)

flask_security.forms.verify_and_update_password = verify_and_update_password_custom


我不确定是否在其他地方使用了它。以上是出于我自己的目的。如果确实在其他地方调用了它,则只需将其猴子补丁到任何位置即可。

07-26 09:29
查看更多