Skip to content
Snippets Groups Projects
Unverified Commit 94499517 authored by Alexandre Ferland's avatar Alexandre Ferland Committed by GitHub
Browse files

Merge branch 'master' into master

parents 2277533d c6f63c7f
No related branches found
No related tags found
No related merge requests found
language: python
sudo: required
dist: xenial
dist: bionic
python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
env:
- FLASK=1.1.1
- FLASK=1.1.2
- FLASK=1.0.4
- FLASK=0.12.4
- FLASK=0.12.5
install:
- pip install Flask==$FLASK
- pip install -r dev_requirements.txt
......
Flask-SimpleLDAP
================
[![Build Status](https://travis-ci.org/admiralobvious/flask-simpleldap.svg?branch=master)](https://travis-ci.org/admiralobvious/flask-simpleldap)
[![Build Status](https://travis-ci.com/alexferl/flask-simpleldap.svg?branch=master)](https://travis-ci.com/alexferl/flask-simpleldap)
Flask-SimpleLDAP provides LDAP authentication for Flask.
Flask-SimpleLDAP is compatible with and tested on Python 3.5, 3.6 and 3.7.
Quickstart
----------
......@@ -13,40 +15,46 @@ First, install Flask-SimpleLDAP:
$ pip install flask-simpleldap
Flask-SimpleLDAP depends, and will install for you, recent versions of Flask
(0.12.4 or later) and [pyldap](https://github.com/pyldap/pyldap). Flask-SimpleLDAP is compatible
with and tested on Python 3.5, 3.6 and 3.7.
(0.12.4 or later) and [python-ldap](https://python-ldap.org/).
Please consult the [python-ldap installation instructions](https://www.python-ldap.org/en/latest/installing.html) if you get an error during installation.
Next, add a ``LDAP`` instance to your code and at least the three
required configuration options:
Next, add an ``LDAP`` instance to your code and at least the three
required configuration options. The complete sample from
[examples/basic_auth/app.py](examples/basic_auth/app.py) looks like this:
```python
from flask import Flask
from flask import Flask, g
from flask_simpleldap import LDAP
app = Flask(__name__)
#app.config['LDAP_HOST'] = 'ldap.example.org' # defaults to localhost
app.config['LDAP_BASE_DN'] = 'OU=users,dc=example,dc=org'
app.config['LDAP_USERNAME'] = 'CN=user,OU=Users,DC=example,DC=org'
app.config['LDAP_PASSWORD'] = 'password'
ldap = LDAP(app)
@app.route('/ldap')
@ldap.login_required
def ldap_protected():
return 'Success!'
@app.route('/')
@ldap.basic_auth_required
def index():
return 'Welcome, {0}!'.format(g.ldap_username)
if __name__ == '__main__':
app.run()
```
You can take a look at [examples/groups](examples/groups) for a more complete
example using LDAP groups.
When the user visits the protected URL, the browser will prompt for the
login and password via the built-in HTTP authentication window. Note that
with the default value of `LDAP_USER_OBJECT_FILTER` the login is expected
to match the [`userPrincipalName` attribute](https://ldapwiki.com/wiki/UserPrincipalName)
of the LDAP user, e.g. `me@mydomain.com`.
You can also take a look at [examples/blueprints](examples/blueprints) for an
example using Flask's
Once you get the basic example working, check out the more complex ones:
* [examples/groups](examples/groups) demostrates using:
* `@ldap.login_required` for form/cookie-based auth, instead of basic HTTP authentication.
* `@ldap.group_required()` to restrict access to pages based on the user's LDAP groups.
* [examples/blueprints](examples/blueprints) implements the same functionality, but uses Flask's
[application factories](http://flask.pocoo.org/docs/patterns/appfactories/)
and [blueprints](http://flask.pocoo.org/docs/blueprints/).
......@@ -59,7 +67,7 @@ configuration, add the following at least LDAP_USER_OBJECT_FILTER and
LDAP_USER_OBJECT_FILTER.
```python
from flask import Flask
from flask import Flask, g
from flask_simpleldap import LDAP
app = Flask(__name__)
......@@ -84,16 +92,13 @@ app.config['LDAP_GROUP_MEMBER_FILTER_FIELD'] = "cn"
ldap = LDAP(app)
@app.route('/ldap')
@ldap.login_required
def ldap_protected():
return 'Success!'
@app.route('/')
@ldap.basic_auth_required
def index():
return 'Welcome, {0}!'.format(g.ldap_username)
if __name__ == '__main__':
app.run()
```
Resources
......
from flask import Flask, g, request, session, redirect, url_for
from flask import Flask, g
from flask_simpleldap import LDAP
app = Flask(__name__)
app.secret_key = 'dev key'
app.debug = True
app.config['LDAP_HOST'] = 'ldap.example.org'
#app.config['LDAP_HOST'] = 'ldap.example.org' # defaults to localhost
app.config['LDAP_BASE_DN'] = 'OU=users,dc=example,dc=org'
app.config['LDAP_USERNAME'] = 'CN=user,OU=Users,DC=example,DC=org'
app.config['LDAP_PASSWORD'] = 'password'
......
from flask import Flask, g, request, session, redirect, url_for
from flask import Flask, g
from flask_simpleldap import LDAP
app = Flask(__name__)
app.secret_key = 'dev key'
app.debug = True
app.config['LDAP_OPENLDAP'] = True
app.config['LDAP_OBJECTS_DN'] = 'dn'
# Base
app.config['LDAP_REALM_NAME'] = 'OpenLDAP Authentication'
app.config['LDAP_HOST'] = 'openldap.example.org'
app.config['LDAP_BASE_DN'] = 'dc=users,dc=openldap,dc=org'
app.config['LDAP_USERNAME'] = 'cn=user,ou=servauth-users,dc=users,dc=openldap,dc=org'
app.config['LDAP_PASSWORD'] = 'password'
# OpenLDAP
app.config['LDAP_OPENLDAP'] = True
app.config['LDAP_OBJECTS_DN'] = 'dn'
app.config['LDAP_USER_OBJECT_FILTER'] = '(&(objectclass=inetOrgPerson)(uid=%s))'
# Groups
app.config['LDAP_GROUP_MEMBERS_FIELD'] = "uniquemember"
app.config['LDAP_GROUP_OBJECT_FILTER'] = "(&(objectclass=groupOfUniqueNames)(cn=%s))"
app.config['LDAP_GROUP_MEMBER_FILTER'] = "(&(cn=*)(objectclass=groupOfUniqueNames)(uniquemember=%s))"
app.config['LDAP_GROUP_MEMBER_FILTER_FIELD'] = "cn"
ldap = LDAP(app)
@app.route('/')
......
......@@ -245,6 +245,7 @@ class LDAP(object):
current_app.config['LDAP_USER_GROUPS_FIELD']]
result = [re.findall(b'(?:cn=|CN=)(.*?),', group)[0]
for group in groups]
result = [r.decode('utf-8') for r in result]
return result
except ldap.LDAPError as e:
raise LDAPException(self.error(e.args))
......@@ -269,6 +270,7 @@ class LDAP(object):
records[0][1]:
members = records[0][1][
current_app.config['LDAP_GROUP_MEMBERS_FIELD']]
members = [m.decode('utf-8') for m in members]
return members
except ldap.LDAPError as e:
raise LDAPException(self.error(e.args))
......@@ -297,8 +299,12 @@ class LDAP(object):
@wraps(func)
def wrapped(*args, **kwargs):
if g.user is None:
next_path=request.full_path or request.path
if next_path == '/?':
return redirect(
url_for(current_app.config['LDAP_LOGIN_VIEW']))
return redirect(url_for(current_app.config['LDAP_LOGIN_VIEW'],
next=request.full_path or request.path))
next=next_path))
return func(*args, **kwargs)
return wrapped
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment