From 592a74670f61e0843a7e0bdaa5f0aed08f493256 Mon Sep 17 00:00:00 2001 From: Adam Mertz Date: Mon, 5 Apr 2021 18:09:54 -0500 Subject: [PATCH 1/4] Fix case request is already signed --- djangosaml2idp/views.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/djangosaml2idp/views.py b/djangosaml2idp/views.py index 401ca76..a727d11 100644 --- a/djangosaml2idp/views.py +++ b/djangosaml2idp/views.py @@ -376,6 +376,21 @@ def get(self, request: HttpRequest, *args, **kwargs): resp = idp_server.create_logout_response(req_info.message, [binding]) + # Case request is already signed + if isinstance(resp, str): + binding, destination = idp_server.pick_binding( + "single_logout_service", [binding], "spsso", req_info + ) + html_response = self.create_html_response( + request, + binding=binding, + authn_resp=resp, + destination=destination, + relay_state=relay_state + ) + logout(request) + return self.render_response(request, html_response, None) + ''' # TODO: SOAP # if binding == BINDING_SOAP: From aca56dbaae61922896578cb76cbb1874427bdab3 Mon Sep 17 00:00:00 2001 From: Adam Mertz Date: Thu, 8 Apr 2021 21:35:54 -0500 Subject: [PATCH 2/4] Write test to confirm bug --- djangosaml2idp/views.py | 26 +++++++++++++------------- tests/private.pem | 16 ++++++++++++++++ tests/public.pem | 14 ++++++++++++++ tests/settings.py | 6 ++++-- tests/test_views.py | 15 ++++++++++++++- 5 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 tests/private.pem create mode 100644 tests/public.pem diff --git a/djangosaml2idp/views.py b/djangosaml2idp/views.py index a727d11..c3af40a 100644 --- a/djangosaml2idp/views.py +++ b/djangosaml2idp/views.py @@ -377,19 +377,19 @@ def get(self, request: HttpRequest, *args, **kwargs): resp = idp_server.create_logout_response(req_info.message, [binding]) # Case request is already signed - if isinstance(resp, str): - binding, destination = idp_server.pick_binding( - "single_logout_service", [binding], "spsso", req_info - ) - html_response = self.create_html_response( - request, - binding=binding, - authn_resp=resp, - destination=destination, - relay_state=relay_state - ) - logout(request) - return self.render_response(request, html_response, None) + # if isinstance(resp, str): + # binding, destination = idp_server.pick_binding( + # "single_logout_service", [binding], "spsso", req_info + # ) + # html_response = self.create_html_response( + # request, + # binding=binding, + # authn_resp=resp, + # destination=destination, + # relay_state=relay_state + # ) + # logout(request) + # return self.render_response(request, html_response, None) ''' # TODO: SOAP diff --git a/tests/private.pem b/tests/private.pem new file mode 100644 index 0000000..3ef20a0 --- /dev/null +++ b/tests/private.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAPXIJ5Kpr24dHEFY +wKZKc3N2wTKey2q3JPbnuDo9J2NVAOzX0Aj32ZpnBg8VBDRdvv2+uxcIRqTSfvGh +54b/K+FtRXniFGjt+G+cUsFmCAoRqi1Po/qPECZfDWBujNeGWQC7LcYYauKRKXdl +ddunhs5US8nLa3g5qJwd8RyQ12nNAgMBAAECgYEA6qiVt75QYvZiIrXFAT916NiJ +7nWTyyhen2lvCBOZBoqC3p3R3q4cUQFp1H6BTCnxDrzKTVw2bmkWkEa/EbGQxsOc +xkR13cs8fyx+DLoakdZJHQGMUlPIjBiPv1iyeXKSghiX12NPdLzmT9yh8syYTRBg +A02NB/ptN7zGn035gtUCQQD7YOstkw48vUeG5d0pHD1mBaY9hVh3knBLyYkJvOTf +anojq2aE/hOpH2j3E0WS6Iig99XcerZu2Qxg93kU9KQ3AkEA+kzlRec5S09qT3oF +EgjJdqS9OrmZBVNys9fRWmeVxitdkk82CBtguprH3zil64dEmve8L7af+a9Cc9ts +c+qoGwJAaMKLQAL4+/clx+IjuO476DiSfzEDHVG52tuycIx4FWOaYyMbJnF8YA7m +/5DYfdDKn8qpJak+PhPWRNLdcw5BIQJARi6ZeuhCoGM8I9zK3yunkaTPik/QIDYt +y0+QXBD/Zfly2ztqowtKLAiKUoTHwSrEic887QQABzqlH2c/GaGKUQJAJGNs6eVS +3Wtj0Uuafpuu96qdLQ2et8IExtL1W8OO1/A+GiAGEAQS7pJV8cjmqeigRy1fD7Tp +CLtOh2fsKqeGNQ== +-----END PRIVATE KEY----- diff --git a/tests/public.pem b/tests/public.pem new file mode 100644 index 0000000..f626537 --- /dev/null +++ b/tests/public.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICOjCCAaOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADA6MQswCQYDVQQGEwJ1czEN +MAsGA1UECAwEYmxhaDENMAsGA1UECgwEYmxhaDENMAsGA1UEAwwEYmxhaDAeFw0y +MTA0MDkwMjA2MjNaFw0yMjA0MDkwMjA2MjNaMDoxCzAJBgNVBAYTAnVzMQ0wCwYD +VQQIDARibGFoMQ0wCwYDVQQKDARibGFoMQ0wCwYDVQQDDARibGFoMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQD1yCeSqa9uHRxBWMCmSnNzdsEynstqtyT257g6 +PSdjVQDs19AI99maZwYPFQQ0Xb79vrsXCEak0n7xoeeG/yvhbUV54hRo7fhvnFLB +ZggKEaotT6P6jxAmXw1gbozXhlkAuy3GGGrikSl3ZXXbp4bOVEvJy2t4OaicHfEc +kNdpzQIDAQABo1AwTjAdBgNVHQ4EFgQUM0Wt6vN/tu1bRZ4Cm8PXEe/CM+gwHwYD +VR0jBBgwFoAUM0Wt6vN/tu1bRZ4Cm8PXEe/CM+gwDAYDVR0TBAUwAwEB/zANBgkq +hkiG9w0BAQ0FAAOBgQCwHt6pVPil8Q6cXXGUp0G6dbwu8ICxaxJp6tJ1kbbzdc+I +fNbDa2P5HVB3KxsBrDoyd7eGdY4OgnmPKqxMajhXB/gPHohH7xnBVnKun4YMKR9k +nQ6xCUWg5dhMtc8hTSi/9hzuGRwvsPQuU8QoUQNB+QKpccdB2/U8BsX9K4CJEA== +-----END CERTIFICATE----- diff --git a/tests/settings.py b/tests/settings.py index 68c7c12..8a68e21 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -66,9 +66,11 @@ ('%s/sso/redirect' % BASE_URL, saml2.BINDING_HTTP_REDIRECT), ], }, + 'sign_response': True, 'name_id_format': [NAMEID_FORMAT_EMAILADDRESS, NAMEID_FORMAT_UNSPECIFIED], - } + }, }, - + 'key_file': PROJECT_ROOT + '/private.pem', + 'cert_file': PROJECT_ROOT + '/public.pem', 'valid_for': 365 * 24, } diff --git a/tests/test_views.py b/tests/test_views.py index 20456dc..e1ddb06 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -1,4 +1,5 @@ import base64 +import pathlib from urllib import parse import pytest @@ -85,7 +86,7 @@ def sp_conf_dict() -> dict: } }, "metadata": { - "local": ["tests/xml/metadata/idp_metadata.xml"] + "local": [str(pathlib.Path(__file__).parent / "xml/metadata/idp_metadata.xml")] } } @@ -591,6 +592,18 @@ def test_slo_view_works_properly_redirect(self, sp_metadata_xml, logged_in_reque assert isinstance(response, HttpResponse) + @pytest.mark.django_db + def test_sign_assertions_true(self, sp_metadata_xml, logged_in_request, saml_logout_request_factory, sp_conf_dict): + # TODO: Cannot get "settings.SAML_IDP_CONFIG" to be modified and loaded so I just modified + # the current settings.py to cause the error. I only want to modify settings for this test and + # set the config to sign_response = True. + ServiceProvider.objects.create(entity_id='test_generic_sp', local_metadata=sp_metadata_xml) + + logged_in_request.GET['SAMLRequest'] = saml_logout_request_factory() + response = LogoutProcessView.as_view()(logged_in_request) + + assert response.status_code == 302 + class TestMetadata: @pytest.mark.django_db From 5bc26e90fd49416e9215380bf64241281355ebe0 Mon Sep 17 00:00:00 2001 From: Adam Mertz Date: Tue, 25 May 2021 19:28:32 -0500 Subject: [PATCH 3/4] uncomment block --- djangosaml2idp/views.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/djangosaml2idp/views.py b/djangosaml2idp/views.py index c3af40a..a727d11 100644 --- a/djangosaml2idp/views.py +++ b/djangosaml2idp/views.py @@ -377,19 +377,19 @@ def get(self, request: HttpRequest, *args, **kwargs): resp = idp_server.create_logout_response(req_info.message, [binding]) # Case request is already signed - # if isinstance(resp, str): - # binding, destination = idp_server.pick_binding( - # "single_logout_service", [binding], "spsso", req_info - # ) - # html_response = self.create_html_response( - # request, - # binding=binding, - # authn_resp=resp, - # destination=destination, - # relay_state=relay_state - # ) - # logout(request) - # return self.render_response(request, html_response, None) + if isinstance(resp, str): + binding, destination = idp_server.pick_binding( + "single_logout_service", [binding], "spsso", req_info + ) + html_response = self.create_html_response( + request, + binding=binding, + authn_resp=resp, + destination=destination, + relay_state=relay_state + ) + logout(request) + return self.render_response(request, html_response, None) ''' # TODO: SOAP From 5adc6136a3dfbdf1f094582e9abee501b5503880 Mon Sep 17 00:00:00 2001 From: Adam Mertz Date: Tue, 25 May 2021 19:37:05 -0500 Subject: [PATCH 4/4] drop todo --- tests/test_views.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_views.py b/tests/test_views.py index e1ddb06..80666af 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -594,9 +594,6 @@ def test_slo_view_works_properly_redirect(self, sp_metadata_xml, logged_in_reque @pytest.mark.django_db def test_sign_assertions_true(self, sp_metadata_xml, logged_in_request, saml_logout_request_factory, sp_conf_dict): - # TODO: Cannot get "settings.SAML_IDP_CONFIG" to be modified and loaded so I just modified - # the current settings.py to cause the error. I only want to modify settings for this test and - # set the config to sign_response = True. ServiceProvider.objects.create(entity_id='test_generic_sp', local_metadata=sp_metadata_xml) logged_in_request.GET['SAMLRequest'] = saml_logout_request_factory()