Authenticate with Flask-LDAP3-Login based on group membership

8.1k Views Asked by At

I'm new to Flask and I'm trying out Flask-LDAP3-Login.

I've followed the documentation here and i have it working which is great: https://flask-ldap3-login.readthedocs.io/en/latest/index.html

How would i go about authenticating a user based on whether they are a member of a specific group? I see the docs mention group filtering but i'm not sure how to put it all together.

3

There are 3 best solutions below

0
On BEST ANSWER

If anyone is curious, i solved this myself doing the following:

First, i integrated flask-ldap3-login with Flask-SQLAlchemy using steps here - https://github.com/nickw444/flask-ldap3-login/issues/26

My save user method now looks like this:

@ldap_manager.save_user
def save_user(dn, username, data, memberships):
    id=int(data.get("uidNumber"))
    if 'group-goes-here' in data.get("memberOf"):
        user=User.query.filter_by(id=id).first()
        if not user:
            user=User(
                id=int(id),
                dn=dn,
                username=username,
                email=data['mail'],
                firstname=data['givenName'],
                lastname=data['sn']
            )
            db.session.add(user)
            db.session.commit()

        return user

So basically provided the user enters valid LDAP credentials it goes to AD to retrieve their group memberships and its a simple if 'group-goes-here' in data.get("memberOf"): determines whether to save the user in my User model and return it back to the handler.

@auth.route('/login', methods=['GET', 'POST'])
def login():
    # Redirect users who are not logged in.
    form = LDAPLoginForm()
    if form.validate_on_submit():
        if form.user:
            login_user(form.user)
        else:
            flash('Login Failed', 'warning')
            return redirect(url_for('auth.login'))
        return redirect(url_for('main.home'))

Hope this helps!

3
On

Do you have a ldap server ? if not go to https://www.openldap.org/ and follow instructions on how to install openldap server if you prefer a docker container then go here https://github.com/osixia/docker-openldap and follow steps to get the container up and running then go here https://ldap3.readthedocs.io/tutorial.html

pip install ldap3 on the machine which has your python env or another python container (same bridge network as your ldap container)

open python console and type the following commands

>>> from ldap3 import Server, Connection, ALL
>>> server = Server('ipa.demo1.freeipa.org')
>>> conn = Connection(server)
>>> conn.bind()
True 

first with this free ldap server ipa.demo1.freeipa.org and then with your own ldap server ip address

0
On

The LDAP_USER_OBJECT_FILTER can be used to check group membership. If a user is not found within the group, an authentication fail will be produced. This is taken from the flask-ldap3-login docs:

Specifies what object filter to apply when searching for users. Defaults to '(objectclass=person)'


Matching direct members of a group:

app.config['LDAP_USER_OBJECT_FILTER'] = '(objectclass=person)(memberOf=<DN of Group>)'

For nested group membership you can use LDAP_MATCHING_RULE_IN_CHAIN:

app.config['LDAP_USER_OBJECT_FILTER'] = '(objectclass=person)(memberOf:1.2.840.113556.1.4.1941:=<DN of Group>)'

The Microsoft Search Filter Syntax docs state:

This is a special "extended" match operator that walks the chain of ancestry in objects all the way to the root until it finds a match.