Skip to content

Commit 8a809c8

Browse files
committed
- chore: upgrade to pysaml 7.1.0
- feat: conf.py takes sp_kwargs to extend the customization of unit tests - chore: RequestedAuthnContext updated to pysaml2 7.1 (IdentityPython/pysaml2#807)
1 parent 97a55ef commit 8a809c8

File tree

5 files changed

+48
-30
lines changed

5 files changed

+48
-30
lines changed

djangosaml2/tests/__init__.py

+36
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,41 @@ def test_unknown_idp(self):
270270
response = self.client.get(reverse('saml2_login')+'?idp=https://unknown.org')
271271
self.assertEqual(response.status_code, 403)
272272

273+
274+
def test_login_authn_context(self):
275+
sp_kwargs = {"requested_authn_context": {
276+
"authn_context_class_ref": [
277+
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
278+
"urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient",
279+
],
280+
"comparison": "minimum",
281+
}
282+
}
283+
284+
# monkey patch SAML configuration
285+
settings.SAML_CONFIG = conf.create_conf(
286+
sp_host='sp.example.com',
287+
idp_hosts=['idp.example.com'],
288+
metadata_file='remote_metadata_one_idp.xml',
289+
sp_kwargs=sp_kwargs
290+
)
291+
292+
response = self.client.get(reverse('saml2_login'))
293+
self.assertEqual(response.status_code, 302)
294+
location = response['Location']
295+
296+
url = urlparse(location)
297+
self.assertEqual(url.hostname, 'idp.example.com')
298+
self.assertEqual(url.path, '/simplesaml/saml2/idp/SSOService.php')
299+
300+
params = parse_qs(url.query)
301+
self.assertIn('SAMLRequest', params)
302+
303+
saml_request = params['SAMLRequest'][0]
304+
self.assertIn('urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', decode_base64_and_inflate(
305+
saml_request).decode('utf-8'))
306+
307+
273308
def test_login_one_idp(self):
274309
# monkey patch SAML configuration
275310
settings.SAML_CONFIG = conf.create_conf(
@@ -294,6 +329,7 @@ def test_login_one_idp(self):
294329
self.assertIn('AuthnRequest xmlns', decode_base64_and_inflate(
295330
saml_request).decode('utf-8'))
296331

332+
297333
# if we set a next arg in the login view, it is preserverd
298334
# in the RelayState argument
299335
nexturl = '/another-view/'

djangosaml2/tests/conf.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919

2020

2121
def create_conf(sp_host='sp.example.com', idp_hosts=['idp.example.com'],
22-
metadata_file='remote_metadata.xml', authn_requests_signed=None):
22+
metadata_file='remote_metadata.xml', authn_requests_signed=None,
23+
sp_kwargs:dict={}):
2324

2425
try:
2526
from saml2.sigver import get_xmlsec_binary
@@ -89,6 +90,7 @@ def create_conf(sp_host='sp.example.com', idp_hosts=['idp.example.com'],
8990
},
9091
'valid_for': 24,
9192
}
93+
config['service']['sp'].update(**sp_kwargs)
9294

9395
if authn_requests_signed is not None:
9496
config['service']['sp']['authn_requests_signed'] = authn_requests_signed

djangosaml2/views.py

-23
Original file line numberDiff line numberDiff line change
@@ -157,27 +157,6 @@ def load_sso_kwargs_scoping(self, sso_kwargs):
157157
)
158158
sso_kwargs['scoping'] = idp_scoping
159159

160-
def load_sso_kwargs_authn_context(self, sso_kwargs):
161-
# this would work when https://github.com/IdentityPython/pysaml2/pull/807
162-
ac = getattr(self.conf, '_sp_requested_authn_context', {})
163-
164-
# this works even without https://github.com/IdentityPython/pysaml2/pull/807
165-
# hopefully to be removed soon !
166-
if not ac:
167-
scs = getattr(
168-
settings, 'SAML_CONFIG', {}
169-
).get('service', {}).get('sp', {})
170-
ac = scs.get('requested_authn_context', {})
171-
# end transitional things to be removed soon !
172-
173-
if ac:
174-
sso_kwargs["requested_authn_context"] = RequestedAuthnContext(
175-
authn_context_class_ref=[
176-
AuthnContextClassRef(ref) for ref in ac['authn_context_class_ref']
177-
],
178-
comparison=ac.get('comparison', "minimum"),
179-
)
180-
181160
def load_sso_kwargs(self, sso_kwargs):
182161
""" Inherit me if you want to put your desidered things in sso_kwargs """
183162

@@ -313,8 +292,6 @@ def get(self, request, *args, **kwargs):
313292
# Enrich sso_kwargs ...
314293
# idp scoping
315294
self.load_sso_kwargs_scoping(sso_kwargs)
316-
# authn context
317-
self.load_sso_kwargs_authn_context(sso_kwargs)
318295
# other customization to be inherited
319296
self.load_sso_kwargs(sso_kwargs)
320297

docs/source/contents/setup.rst

+6-3
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,12 @@ Authn Context
218218

219219
We can define the authentication context in settings.SAML_CONFIG['service']['sp'] as follows::
220220

221-
'requested_authn_context': {
222-
'authn_context_class_ref': [saml2.saml.AUTHN_PASSWORD_PROTECTED],
223-
'comparison': "exact"
221+
"requested_authn_context": {
222+
"authn_context_class_ref": [
223+
"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
224+
"urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient",
225+
],
226+
"comparison": "minimum",
224227
}
225228

226229

setup.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def read(*rnames):
2424

2525
setup(
2626
name='djangosaml2',
27-
version='1.3.4',
27+
version='1.3.5',
2828
description='pysaml2 integration for Django',
2929
long_description=read('README.md'),
3030
long_description_content_type='text/markdown',
@@ -52,8 +52,8 @@ def read(*rnames):
5252
keywords="django,pysaml2,sso,saml2,federated authentication,authentication",
5353
author="Yaco Sistemas and independent contributors",
5454
author_email="[email protected]",
55-
maintainer="Jozef Knaperek",
56-
url="https://github.com/knaperek/djangosaml2",
55+
maintainer="Giuseppe De Marco",
56+
url="https://github.com/IdentityPython/djangosaml2",
5757
download_url="https://pypi.org/project/djangosaml2/",
5858
license='Apache 2.0',
5959
packages=find_packages(exclude=["tests", "tests.*"]),

0 commit comments

Comments
 (0)