1
+ import enum
1
2
import re
2
3
3
4
import ldap3
4
5
from jupyterhub .auth import Authenticator
5
6
from ldap3 .utils .conv import escape_filter_chars
6
- from traitlets import Bool , Int , List , Unicode , Union , validate
7
+ from traitlets import Bool , Int , List , Unicode , Union , UseEnum , observe , validate
8
+
9
+
10
+ class TlsStrategy (enum .Enum ):
11
+ """
12
+ Represents a SSL/TLS strategy for LDAPAuthenticator to use when interacting
13
+ with the LDAP server.
14
+ """
15
+
16
+ before_bind = 1
17
+ on_connect = 2
18
+ insecure = 3
7
19
8
20
9
21
class LDAPAuthenticator (Authenticator ):
@@ -20,23 +32,61 @@ class LDAPAuthenticator(Authenticator):
20
32
help = """
21
33
Port on which to contact the LDAP server.
22
34
23
- Defaults to `636` if `use_ssl` is set, `389` otherwise.
35
+ Defaults to `636` if `tls_strategy="on_connect"` is set, `389`
36
+ otherwise.
24
37
""" ,
25
38
)
26
39
27
40
def _server_port_default (self ):
28
- if self .use_ssl :
41
+ if self .tls_strategy == TlsStrategy . on_connect :
29
42
return 636 # default SSL port for LDAP
30
43
else :
31
44
return 389 # default plaintext port for LDAP
32
45
33
46
use_ssl = Bool (
34
- False ,
47
+ None ,
48
+ allow_none = True ,
49
+ config = True ,
50
+ help = """
51
+ `use_ssl` is deprecated since 2.0. `use_ssl=True` translates to configuring
52
+ `tls_strategy="on_connect"`, but `use_ssl=False` (previous default) doesn't
53
+ translate to anything.
54
+ """ ,
55
+ )
56
+
57
+ @observe ("use_ssl" )
58
+ def _observe_use_ssl (self , change ):
59
+ if change .new :
60
+ self .tls_strategy = TlsStrategy .on_connect
61
+ self .log .warning (
62
+ "LDAPAuthenticator.use_ssl is deprecated in 2.0 in favor of LDAPAuthenticator.tls_strategy, "
63
+ 'instead of configuring use_ssl=True, configure use tls_strategy="on_connect" from now on.'
64
+ )
65
+ else :
66
+ self .log .warning (
67
+ "LDAPAuthenticator.use_ssl is deprecated in 2.0 in favor of LDAPAuthenticator.tls_strategy, "
68
+ "you can stop configuring use_ssl=False from now on as doing so has no effect."
69
+ )
70
+
71
+ tls_strategy = UseEnum (
72
+ TlsStrategy ,
73
+ default_value = TlsStrategy .before_bind ,
35
74
config = True ,
36
75
help = """
37
- Use SSL to communicate with the LDAP server.
76
+ When LDAPAuthenticator connects to the LDAP server, it can establish a
77
+ SSL/TLS connection directly, or do it before binding, which is LDAP
78
+ terminology for authenticating and sending sensitive credentials.
79
+
80
+ The protocol LDAPv3 deprecated establishing a SSL/TLS connection
81
+ directly (`tls_strategy="on_connect"`) in favor of upgrading the
82
+ connection to SSL/TLS before binding (`tls_strategy="before_bind"`).
83
+
84
+ Supported `tls_strategy` values are: - "before_bind" (default) -
85
+ "on_connect" (deprecated in LDAPv3, associated with use of port 636) -
86
+ "insecure"
38
87
39
- Deprecated in version 3 of LDAP. Your LDAP server must be configured to support this, however.
88
+ When configuring `tls_strategy="on_connect"`, the default value of
89
+ `server_port` becomes 636.
40
90
""" ,
41
91
)
42
92
@@ -297,14 +347,26 @@ def resolve_username(self, username_supplied_by_user):
297
347
return (user_dn , response [0 ]["dn" ])
298
348
299
349
def get_connection (self , userdn , password ):
350
+ if self .tls_strategy == TlsStrategy .on_connect :
351
+ use_ssl = True
352
+ auto_bind = ldap3 .AUTO_BIND_NO_TLS
353
+ elif self .tls_strategy == TlsStrategy .before_bind :
354
+ use_ssl = False
355
+ auto_bind = ldap3 .AUTO_BIND_TLS_BEFORE_BIND
356
+ else : # TlsStrategy.insecure
357
+ use_ssl = False
358
+ auto_bind = ldap3 .AUTO_BIND_NO_TLS
359
+
300
360
server = ldap3 .Server (
301
- self .server_address , port = self .server_port , use_ssl = self .use_ssl
302
- )
303
- auto_bind = (
304
- ldap3 .AUTO_BIND_NO_TLS if self .use_ssl else ldap3 .AUTO_BIND_TLS_BEFORE_BIND
361
+ self .server_address ,
362
+ port = self .server_port ,
363
+ use_ssl = use_ssl ,
305
364
)
306
365
conn = ldap3 .Connection (
307
- server , user = userdn , password = password , auto_bind = auto_bind
366
+ server ,
367
+ user = userdn ,
368
+ password = password ,
369
+ auto_bind = auto_bind ,
308
370
)
309
371
return conn
310
372
0 commit comments