-
Notifications
You must be signed in to change notification settings - Fork 38
/
ldap_app.py
134 lines (100 loc) · 3.86 KB
/
ldap_app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from flask import Flask, redirect, render_template_string, url_for
from flask_login import LoginManager, UserMixin, current_user, login_user
from flask_ldap3_login import LDAP3LoginManager
from flask_ldap3_login.forms import LDAPLoginForm
app = Flask(__name__)
app.config["SECRET_KEY"] = "secret"
app.config["DEBUG"] = True
# Setup LDAP Configuration Variables. Change these to your own settings.
# All configuration directives can be found in the documentation.
# Hostname of your LDAP Server
app.config["LDAP_HOST"] = "ad.mydomain.com"
# Base DN of your directory
app.config["LDAP_BASE_DN"] = "dc=mydomain,dc=com"
# Users DN to be prepended to the Base DN
app.config["LDAP_USER_DN"] = "ou=users"
# Groups DN to be prepended to the Base DN
app.config["LDAP_GROUP_DN"] = "ou=groups"
# The RDN attribute for your user schema on LDAP
app.config["LDAP_USER_RDN_ATTR"] = "cn"
# The Attribute you want users to authenticate to LDAP with.
app.config["LDAP_USER_LOGIN_ATTR"] = "mail"
# The Username to bind to LDAP with
app.config["LDAP_BIND_USER_DN"] = None
# The Password to bind to LDAP with
app.config["LDAP_BIND_USER_PASSWORD"] = None
login_manager = LoginManager(app) # Setup a Flask-Login Manager
ldap_manager = LDAP3LoginManager(app) # Setup a LDAP3 Login Manager.
# Create a dictionary to store the users in when they authenticate
# This example stores users in memory.
users = {}
# Declare an Object Model for the user, and make it comply with the
# flask-login UserMixin mixin.
class User(UserMixin):
def __init__(self, dn, username, data):
self.dn = dn
self.username = username
self.data = data
def __repr__(self):
return self.dn
def get_id(self):
return self.dn
# Declare a User Loader for Flask-Login.
# Simply returns the User if it exists in our 'database', otherwise
# returns None.
@login_manager.user_loader
def load_user(id):
if id in users:
return users[id]
return None
# Declare The User Saver for Flask-Ldap3-Login
# This method is called whenever a LDAPLoginForm() successfully validates.
# Here you have to save the user, and return it so it can be used in the
# login controller.
@ldap_manager.save_user
def save_user(dn, username, data, memberships):
user = User(dn, username, data)
users[dn] = user
return user
# Declare some routes for usage to show the authentication process.
@app.route("/")
def home():
# Redirect users who are not logged in.
if not current_user or current_user.is_anonymous:
return redirect(url_for("login"))
# User is logged in, so show them a page with their cn and dn.
template = """
<h1>Welcome: {{ current_user.data.cn }}</h1>
<h2>{{ current_user.dn }}</h2>
"""
return render_template_string(template)
@app.route("/manual_login")
def manual_login():
# Instead of using the form, you can alternatively authenticate
# using the authenticate method.
# This WILL NOT fire the save_user() callback defined above.
# You are responsible for saving your users.
app.ldap3_login_manager.authenticate("username", "password")
@app.route("/login", methods=["GET", "POST"])
def login():
template = """
{{ get_flashed_messages() }}
{{ form.errors }}
<form method="POST">
<label>Username{{ form.username() }}</label>
<label>Password{{ form.password() }}</label>
{{ form.submit() }}
{{ form.hidden_tag() }}
</form>
"""
# Instantiate a LDAPLoginForm which has a validator to check if the user
# exists in LDAP.
form = LDAPLoginForm()
if form.validate_on_submit():
# Successfully logged in, We can now access the saved user object
# via form.user.
login_user(form.user) # Tell flask-login to log them in.
return redirect("/") # Send them home
return render_template_string(template, form=form)
if __name__ == "__main__":
app.run()