-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.py
More file actions
95 lines (72 loc) · 3.36 KB
/
middleware.py
File metadata and controls
95 lines (72 loc) · 3.36 KB
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
import base64
import hashlib
from tyk.decorators import *
from gateway import TykGateway as tyk
import ldap
# address of the ldap server
ldap_server = "172.17.0.2"
@Hook
def LDAPAuthMiddleware(request, session, metadata, spec):
"""
Function to handle Authentication via LDAP.
Please review the tutorial here:
https://tyk.io/docs/customise-tyk/plugins/rich-plugins/python/custom-auth-python-tutorial/
This middleware expects an 'Authorization' header in the request object. The header will have the format:
'Basic AUTH_STRING'
Where AUTH_STRING is a base64 encoded string of the format:
'username:password'
For this example, the username is expected to have a distinguished name of:
"cn=" + username + ",dc=example,dc=org"
Note that the ldap_server variable is set to the ip address of the LDAP server.
"""
auth_header = request.get_header('Authorization')
if not auth_header:
# Log the error
error_text = "No Auth header"
tyk.log_error(error_text)
# Set the return_overrides object to the appropriate error
request.object.return_overrides.response_code = 400
request.object.return_overrides.response_error = error_text
return request, session, metadata
tyk.log_error(auth_header)
field, sep, value = auth_header.partition("Basic ")
if not value:
# Log the error
error_text = "Incorrect auth header (no value)"
tyk.log_error(error_text)
# Set the return_overrides object to the appropriate error
request.object.return_overrides.response_code = 400
request.object.return_overrides.response_error = error_text
return request, session, metadata
# note the weirdness with bytes vs. strings because we're in python3
value_bytes = bytes(value, 'ascii')
decoded_value = base64.standard_b64decode(value_bytes).decode()
username, password = decoded_value.split(":")
if not (username and password):
# Log the error
error_text = "Incorrect auth header (no username, password)"
tyk.log_error(error_text)
# Set the return_overrides object to the appropriate error
request.object.return_overrides.response_code = 400
request.object.return_overrides.response_error = error_text
return request, session, metadata
user_dn = "cn=" + username + ",dc=example,dc=org"
try:
# initialize ldap and authenticate user using bind
ldap_object = ldap.initialize("ldap://" + ldap_server)
ldap_object.bind_s(user_dn, password)
except ldap.LDAPError as e:
# Log the error
error_text = "Could not authenticate against LDAP with user " + username
tyk.log_error(error_text)
tyk.log_error(str(e))
# Set the return_overrides object to the appropriate error
request.object.return_overrides.response_code = 500
request.object.return_overrides.response_error = error_text + ". -- " + str(e)
return request, session, metadata
# Setting metadata['token'] indicates to Tyk that the authorization was a success. In this case we are setting it
# to the md5sum of the user_dn and the password.
to_hash = user_dn + ":" + password
metadata['token'] = hashlib.md5(to_hash.encode()).hexdigest()
tyk.log("Authorized user: " + username, "info")
return request, session, metadata