Skip to content

Commit fedbd28

Browse files
add assertion param to backed.authenticate and is_authorized functions
1 parent 0b3dc4a commit fedbd28

File tree

3 files changed

+19
-9
lines changed

3 files changed

+19
-9
lines changed

djangosaml2/backends.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def _get_attribute_value(self, django_field: str, attributes: dict, attribute_ma
106106
'value is missing. Probably the user '
107107
'session is expired.')
108108

109-
def authenticate(self, request, session_info=None, attribute_mapping=None, create_unknown_user=True, **kwargs):
109+
def authenticate(self, request, session_info=None, attribute_mapping=None, create_unknown_user=True, assertion=None, **kwargs):
110110
if session_info is None or attribute_mapping is None:
111111
logger.info('Session info or attribute mapping are None')
112112
return None
@@ -121,7 +121,7 @@ def authenticate(self, request, session_info=None, attribute_mapping=None, creat
121121

122122
logger.debug(f'attributes: {attributes}')
123123

124-
if not self.is_authorized(attributes, attribute_mapping, idp_entityid):
124+
if not self.is_authorized(attributes, attribute_mapping, idp_entityid, assertion):
125125
logger.error('Request not authorized')
126126
return None
127127

@@ -194,7 +194,7 @@ def clean_attributes(self, attributes: dict, idp_entityid: str, **kwargs) -> dic
194194
""" Hook to clean or filter attributes from the SAML response. No-op by default. """
195195
return attributes
196196

197-
def is_authorized(self, attributes: dict, attribute_mapping: dict, idp_entityid: str, **kwargs) -> bool:
197+
def is_authorized(self, attributes: dict, attribute_mapping: dict, idp_entityid: str, assertion: object, **kwargs) -> bool:
198198
""" Hook to allow custom authorization policies based on SAML attributes. True by default. """
199199
return True
200200

djangosaml2/views.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ def post(self, request, attribute_mapping=None, create_unknown_user=None):
430430
user = auth.authenticate(request=request,
431431
session_info=session_info,
432432
attribute_mapping=attribute_mapping,
433-
create_unknown_user=create_unknown_user)
433+
create_unknown_user=create_unknown_user,
434+
assertion=response.assertion)
434435
if user is None:
435436
logger.warning(
436437
"Could not authenticate user received in SAML Assertion. Session info: %s", session_info)

tests/testprofiles/tests.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from django.core.exceptions import ImproperlyConfigured
2222
from django.test import TestCase, override_settings
2323
from djangosaml2.backends import Saml2Backend, set_attribute
24+
from saml2.saml import Assertion
2425

2526
from testprofiles.models import TestUser
2627

@@ -104,7 +105,7 @@ def test_extract_user_identifier_params_use_nameid_missing(self):
104105
self.assertEqual(lookup_value, None)
105106

106107
def test_is_authorized(self):
107-
self.assertTrue(self.backend.is_authorized({}, {}, ''))
108+
self.assertTrue(self.backend.is_authorized({}, {}, '', None))
108109

109110
def test_clean_attributes(self):
110111
attributes = {'random': 'dummy', 'value': 123}
@@ -333,9 +334,9 @@ def test_deprecations(self):
333334
class CustomizedBackend(Saml2Backend):
334335
""" Override the available methods with some customized implementation to test customization
335336
"""
336-
def is_authorized(self, attributes, attribute_mapping, idp_entityid: str, **kwargs):
337+
def is_authorized(self, attributes, attribute_mapping, idp_entityid: str, assertion, **kwargs):
337338
''' Allow only staff users from the IDP '''
338-
return attributes.get('is_staff', (None, ))[0] == True
339+
return attributes.get('is_staff', (None, ))[0] == True and getattr(assertion, 'id', None) != None
339340

340341
def clean_attributes(self, attributes: dict, idp_entityid: str, **kwargs) -> dict:
341342
''' Keep only age attribute '''
@@ -368,9 +369,12 @@ def test_is_authorized(self):
368369
'cn': ('John', ),
369370
'sn': ('Doe', ),
370371
}
371-
self.assertFalse(self.backend.is_authorized(attributes, attribute_mapping, ''))
372+
assertion = Assertion()
373+
self.assertFalse(self.backend.is_authorized(attributes, attribute_mapping, '', assertion))
372374
attributes['is_staff'] = (True, )
373-
self.assertTrue(self.backend.is_authorized(attributes, attribute_mapping, ''))
375+
self.assertFalse(self.backend.is_authorized(attributes, attribute_mapping, '', assertion))
376+
assertion.id = 'abcdefg12345'
377+
self.assertTrue(self.backend.is_authorized(attributes, attribute_mapping, '', assertion))
374378

375379
def test_clean_attributes(self):
376380
attributes = {'random': 'dummy', 'value': 123, 'age': '28'}
@@ -396,6 +400,7 @@ def test_authenticate(self):
396400
'age': ('28', ),
397401
'is_staff': (True, ),
398402
}
403+
assertion = Assertion(id='abcdefg12345')
399404

400405
self.assertEqual(self.user.age, '')
401406
self.assertEqual(self.user.is_staff, False)
@@ -409,6 +414,7 @@ def test_authenticate(self):
409414
None,
410415
session_info={'random': 'content'},
411416
attribute_mapping=attribute_mapping,
417+
assertion=assertion,
412418
)
413419
self.assertIsNone(user)
414420

@@ -417,6 +423,7 @@ def test_authenticate(self):
417423
None,
418424
session_info={'ava': attributes, 'issuer': 'dummy_entity_id'},
419425
attribute_mapping=attribute_mapping,
426+
assertion=assertion,
420427
)
421428
self.assertIsNone(user)
422429

@@ -425,6 +432,7 @@ def test_authenticate(self):
425432
None,
426433
session_info={'ava': attributes, 'issuer': 'dummy_entity_id'},
427434
attribute_mapping=attribute_mapping,
435+
assertion=assertion,
428436
)
429437
self.assertIsNone(user)
430438

@@ -433,6 +441,7 @@ def test_authenticate(self):
433441
None,
434442
session_info={'ava': attributes, 'issuer': 'dummy_entity_id'},
435443
attribute_mapping=attribute_mapping,
444+
assertion=assertion,
436445
)
437446

438447
self.assertEqual(user, self.user)

0 commit comments

Comments
 (0)