forked from jeremyschulman/django3-auth-saml2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backends.py
81 lines (64 loc) · 2.91 KB
/
backends.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
from django.contrib.auth.models import User
from django.contrib.auth.backends import RemoteUserBackend
from django.core.handlers.wsgi import WSGIRequest
from saml2.response import AuthnResponse
class SAML2DottedEmailUserBackend(RemoteUserBackend):
"""
By default the User name is going to be set to the email adddress by the
django3_auth_saml2 package. That said, we want to configure the User
first name, last name, and email fields as well; but only if the username
follows the form "firstname.lastname@company.com"
"""
def configure_user(self, request, user: User):
user.email = user.username
name, *_ = user.username.partition('@')
if name.count('.') == 1:
user.first_name, user.last_name = map(str.title, name.split('.'))
user.save()
return super().configure_user(request, user)
class SAML2AttrUserBackend(RemoteUserBackend):
"""
Do not use email as the User name. Use the SAML2 attributes to configure
the username, first name, and last name values. This presumes that the
SAML2 SSO system has been setup to provide the attributes:
* first_name
* last_name
* email
The User name will be set to <first_name>.<last_name> in lower-case.
"""
def authenticate(self, request: WSGIRequest, remote_user: str) -> User:
"""
This method must use the SAML2 attributes to formulate the User name
the way we want it.
"""
saml2_auth_resp: AuthnResponse = request.META['SAML2_AUTH_RESPONSE']
user_ident = saml2_auth_resp.get_identity()
try:
first_name = user_ident['first_name'][0].lower()
last_name = user_ident['last_name'][0].lower()
remote_user = f"{first_name}.{last_name}"
return super().authenticate(request, remote_user)
except KeyError as exc:
missing_attr = exc.args[0]
be_name = self.__class__.__name__
raise PermissionError(f"SAML2 backend {be_name} missing attribute: {missing_attr}")
def configure_user(self, request: WSGIRequest, user: User) -> User:
"""
This method is only called when a new User is created. This method
will use the SAML2 user identity to configure addition properies about
the user. This will include:
* first_name
* last_name
* email
"""
saml2_auth_resp: AuthnResponse = request.META['SAML2_AUTH_RESPONSE']
user_ident = saml2_auth_resp.get_identity()
user.first_name, user.last_name = map(str.title, user.username.split('.'))
try:
user.email = user_ident['email'][0]
user.save()
except KeyError as exc:
missing_attr = exc.args[0]
be_name = self.__class__.__name__
raise PermissionError(f"SAML2 backend {be_name} missing attribute: {missing_attr}")
return user