I'm using flask security to authenticate users. I've made sure the authentication works properly with the http_auth_required
decorator - the user is being validated against the userstore (an SQLAlchemyUserDatastore
in my case), and all is well.
I would like now to use my own authentication method (I'll be using a custom LDAP validation system), while still taking advantage of the things Flask-Security is giving me (things like current_user
). I wrote a custom decorator that looks like this:
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
However, when I look at the http_auth_required
decorator I see that it uses a private function called _check_http_auth
that is doing some stuff that I can't do on my own without accessing private members, like setting the user to the top of the request context stack and sending signals. The code looks like this:
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
So my question is: what is the correct way to have a custom authentication method, while still utilizing Flask-Security to its fullest?