Skip to content

Commit 966316a

Browse files
authored
Merge pull request #106 from francoisfreitag/sigalg
[Waiting #109] Don't pass sigalg parameter when not signing login request
2 parents 56ddcfa + 667b405 commit 966316a

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

djangosaml2/tests/__init__.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
import base64
1818
import datetime
1919
import re
20+
try:
21+
# Prefer PyPI mock over unittest.mock to benefit from backported mock
22+
# features (such as assert_called_once). Valid until Python 3.6.
23+
import mock
24+
except ImportError:
25+
from unittest import mock
2026
from unittest import skip
2127

2228
from django.conf import settings
@@ -504,6 +510,43 @@ def test_idplist_templatetag(self):
504510

505511
self.assertEqual(rendered, expected)
506512

513+
def test_sigalg_not_passed_when_not_signing_request(self):
514+
# monkey patch SAML configuration
515+
settings.SAML_CONFIG = conf.create_conf(
516+
sp_host='sp.example.com',
517+
idp_hosts=['idp.example.com'],
518+
metadata_file='remote_metadata_one_idp.xml',
519+
)
520+
521+
with mock.patch(
522+
'djangosaml2.views.Saml2Client.prepare_for_authenticate',
523+
return_value=('session_id', {'url': 'fake'}),
524+
525+
) as prepare_for_auth_mock:
526+
self.client.get(reverse('saml2_login'))
527+
prepare_for_auth_mock.assert_called_once()
528+
_args, kwargs = prepare_for_auth_mock.call_args
529+
self.assertNotIn('sigalg', kwargs)
530+
531+
def test_sigalg_passed_when_signing_request(self):
532+
# monkey patch SAML configuration
533+
settings.SAML_CONFIG = conf.create_conf(
534+
sp_host='sp.example.com',
535+
idp_hosts=['idp.example.com'],
536+
metadata_file='remote_metadata_one_idp.xml',
537+
)
538+
539+
settings.SAML_CONFIG['service']['sp']['authn_requests_signed'] = True
540+
with mock.patch(
541+
'djangosaml2.views.Saml2Client.prepare_for_authenticate',
542+
return_value=('session_id', {'url': 'fake'}),
543+
544+
) as prepare_for_auth_mock:
545+
self.client.get(reverse('saml2_login'))
546+
prepare_for_auth_mock.assert_called_once()
547+
_args, kwargs = prepare_for_auth_mock.call_args
548+
self.assertIn('sigalg', kwargs)
549+
507550

508551
def test_config_loader(request):
509552
config = SPConfig()

djangosaml2/views.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,17 +191,18 @@ def login(request,
191191
logger.debug('Redirecting user to the IdP via %s binding.', binding)
192192
if binding == BINDING_HTTP_REDIRECT:
193193
try:
194-
# do not sign the xml itself, instead use the sigalg to
195-
# generate the signature as a URL param
196-
sig_alg_option_map = {'sha1': SIG_RSA_SHA1,
197-
'sha256': SIG_RSA_SHA256}
198-
sig_alg_option = getattr(conf, '_sp_authn_requests_signed_alg', 'sha1')
199-
sigalg = sig_alg_option_map[sig_alg_option] if sign_requests else None
200194
nsprefix = get_namespace_prefixes()
195+
if sign_requests:
196+
# do not sign the xml itself, instead use the sigalg to
197+
# generate the signature as a URL param
198+
sig_alg_option_map = {'sha1': SIG_RSA_SHA1,
199+
'sha256': SIG_RSA_SHA256}
200+
sig_alg_option = getattr(conf, '_sp_authn_requests_signed_alg', 'sha1')
201+
kwargs["sigalg"] = sig_alg_option_map[sig_alg_option]
201202
session_id, result = client.prepare_for_authenticate(
202203
entityid=selected_idp, relay_state=came_from,
203-
binding=binding, sign=False, sigalg=sigalg,
204-
nsprefix=nsprefix, **kwargs)
204+
binding=binding, sign=False, nsprefix=nsprefix,
205+
**kwargs)
205206
except TypeError as e:
206207
logger.error('Unable to know which IdP to use')
207208
return HttpResponse(str(e))

setup.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
import codecs
1717
import os
18-
import sys
1918
from setuptools import setup, find_packages
2019

2120

@@ -63,4 +62,8 @@ def read(*rnames):
6362
'Django>=2.2',
6463
'pysaml2>=4.6.0',
6564
],
65+
tests_require=[
66+
# Provides assert_called_once.
67+
'mock;python_version < "3.6"',
68+
]
6669
)

0 commit comments

Comments
 (0)