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?
You can accomplish this with a quick monkey patch. Not ideal, but I'm not sure what else you can do until the Flask-Security team writes in a more elegant way to handle this.
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
I'm not sure if it is used anywhere else. The above works for my own purposes. If it does get called elsewhere, you would just need to monkeypatch it into place wherever that is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With