def testGetLastLogoutResponse(self): settings = self.loadSettingsJSON() request = self.file_contents( join(self.data_path, 'logout_requests', 'logout_request.xml')) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(request) message_wrapper = {'get_data': {'SAMLRequest': message}} auth = OneLogin_Saml2_Auth(message_wrapper, old_settings=settings) auth.process_slo() expectedFragment = ( 'Destination="http://idp.example.com/SingleLogoutService.php"\n' ' InResponseTo="ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e"\n>\n' ' <saml:Issuer>http://stuff.com/endpoints/metadata.php</saml:Issuer>\n' ' <samlp:Status>\n' ' <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />\n' ' </samlp:Status>\n' '</samlp:LogoutResponse>') self.assertIn(expectedFragment, auth.get_last_response_xml()) response = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response.xml')) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(response) message_wrapper = {'get_data': {'SAMLResponse': message}} auth = OneLogin_Saml2_Auth(message_wrapper, old_settings=settings) auth.process_slo() self.assertEqual(response, auth.get_last_response_xml())
def testDeflateBase64Roundtrip(self): """ Tests deflate_and_base64_encode and decode_base64_and_inflate methods of OneLogin_Saml2_Utils """ body = 'Some random string.' encoded = OneLogin_Saml2_Utils.deflate_and_base64_encode(body) self.assertEqual(OneLogin_Saml2_Utils.decode_base64_and_inflate(encoded), body) unicode_body = u'Sömé rändöm nön-äsçïï strïng.' unicode_encoded = OneLogin_Saml2_Utils.deflate_and_base64_encode(unicode_body) self.assertEqual(OneLogin_Saml2_Utils.decode_base64_and_inflate(unicode_encoded), unicode_body)
def get_response(self): """ Returns a Logout Response object. :return: Logout Response deflated and base64 encoded :rtype: string """ return OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__logout_response)
def testIsInValidIssuer(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse Case invalid Issuer """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) plain_message = compat.to_string( OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) plain_message = plain_message.replace( 'http://idp.example.com/', 'http://invalid.issuer.example.com') message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) settings.set_strict(False) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) with self.assertRaisesRegexp(Exception, 'Invalid issuer in the Logout Request'): response_2.is_valid(request_data, raise_exceptions=True)
def testProcessSLOResponseRequestId(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Logout Response with valid and invalid Request ID """ request_data = self.get_request() message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLResponse'] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) request_id = 'wrongID' auth.set_strict(True) auth.process_slo(True, request_id) self.assertEqual(auth.get_errors(), ['invalid_logout_response']) request_id = 'ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e' auth.process_slo(True, request_id) self.assertEqual(len(auth.get_errors()), 0)
def testIsValidWithCapitalization(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse """ request_data = { 'http_host': 'exaMPLe.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) with self.assertRaisesRegex(Exception, 'The LogoutResponse was received at'): response_2.is_valid(request_data, raise_exceptions=True) plain_message = compat.to_string( OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query( request_data).lower() plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) message_3 = OneLogin_Saml2_Utils.deflate_and_base64_encode( plain_message) response_3 = OneLogin_Saml2_Logout_Response(settings, message_3) self.assertTrue(response_3.is_valid(request_data))
def testProcessSLOResponseValidDeletingSession(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Response, validating deleting the local session """ request_data = self.get_request() message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) # FIXME # if (!isset($_SESSION)) { # $_SESSION = array(); # } # $_SESSION['samltest'] = true; # In order to avoid the destination problem plain_message = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLResponse'] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) auth.set_strict(True) auth.process_slo(False) self.assertEqual(len(auth.get_errors()), 0)
def slo_query_string(): """Mock SLO response from Identity Provider.""" xml_file = pkg_resources.resource_filename( __name__, os.path.join('data', 'slo_response.xml')) with open(xml_file) as f: slo_response = saml_utils.deflate_and_base64_encode(f.read()) return urlencode(dict(SAMLResponse=slo_response))
def get_request(self): """ Returns the Logout Request defated, base64encoded :return: Deflated base64 encoded Logout Request :rtype: str object """ return OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__logout_request)
def get_request(self): """ Returns unsigned AuthnRequest. :return: Unsigned AuthnRequest :rtype: str object """ return OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__authn_request)
def testGetXML(self): """ Tests that we can get the logout response XML directly without going through intermediate steps """ response = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response.xml')) settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) logout_response_generated = OneLogin_Saml2_Logout_Response(settings) logout_response_generated.build("InResponseValue") expectedFragment = ( 'Destination="http://idp.example.com/SingleLogoutService.php"\n' ' InResponseTo="InResponseValue"\n>\n' ' <saml:Issuer>http://stuff.com/endpoints/metadata.php</saml:Issuer>\n' ' <samlp:Status>\n' ' <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />\n' ' </samlp:Status>\n' '</samlp:LogoutResponse>') self.assertIn(expectedFragment, logout_response_generated.get_xml()) logout_response_processed = OneLogin_Saml2_Logout_Response( settings, OneLogin_Saml2_Utils.deflate_and_base64_encode(response)) self.assertEqual(response, logout_response_processed.get_xml())
def testIsInValidIssuer(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse Case invalid Issuer """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) plain_message = plain_message.replace('http://idp.example.com/', 'http://invalid.issuer.example.com') message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) settings.set_strict(False) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) self.assertFalse(response_2.is_valid(request_data)) self.assertIn('Invalid issuer in the Logout Response', response_2.get_error())
def testProcessSLORequestSignedResponse(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Request, validating the relayState, a signed LogoutResponse is created and a redirection executed """ settings_info = self.loadSettingsJSON() settings_info["security"]["logoutResponseSigned"] = True request_data = self.get_request() message = self.file_contents(join(self.data_path, "logout_requests", "logout_request_deflated.xml.base64")) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace("http://stuff.com/endpoints/endpoints/sls.php", current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data["get_data"]["SAMLRequest"] = message request_data["get_data"]["RelayState"] = "http://relaystate.com" auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info) auth.set_strict(True) target_url = auth.process_slo(False) parsed_query = parse_qs(urlparse(target_url)[4]) slo_url = settings_info["idp"]["singleLogoutService"]["url"] self.assertIn(slo_url, target_url) self.assertIn("SAMLResponse", parsed_query) self.assertIn("RelayState", parsed_query) self.assertIn("SigAlg", parsed_query) self.assertIn("Signature", parsed_query) self.assertIn("http://relaystate.com", parsed_query["RelayState"]) self.assertIn(OneLogin_Saml2_Constants.RSA_SHA1, parsed_query["SigAlg"])
def testIsValid(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) self.assertFalse(response_2.is_valid(request_data)) self.assertIn('The LogoutResponse was received at', response_2.get_error()) plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message_3 = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) response_3 = OneLogin_Saml2_Logout_Response(settings, message_3) self.assertTrue(response_3.is_valid(request_data))
def testIsValid(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) try: valid = response_2.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The LogoutRequest was received at', e.message) plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message_3 = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) response_3 = OneLogin_Saml2_Logout_Response(settings, message_3) self.assertTrue(response_3.is_valid(request_data))
def testIsInValidRequestId(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse Case invalid request Id """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) plain_message = compat.to_string( OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_id = 'invalid_request_id' settings.set_strict(False) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data, request_id)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) try: valid = response_2.is_valid(request_data, request_id) self.assertFalse(valid) except Exception as e: self.assertIn('The InResponseTo of the Logout Response:', str(e))
def testProcessSLORequestSignedResponse(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Request, validating the relayState, a signed LogoutResponse is created and a redirection executed """ settings_info = self.loadSettingsJSON() settings_info['security']['logoutResponseSigned'] = True request_data = self.get_request() message = self.file_contents( join(self.data_path, 'logout_requests', 'logout_request_deflated.xml.base64')) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLRequest'] = message request_data['get_data']['RelayState'] = 'http://relaystate.com' auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info) auth.set_strict(True) target_url = auth.process_slo(False) parsed_query = parse_qs(urlparse(target_url)[4]) slo_url = settings_info['idp']['singleLogoutService']['url'] self.assertIn(slo_url, target_url) self.assertIn('SAMLResponse', parsed_query) self.assertIn('RelayState', parsed_query) self.assertIn('SigAlg', parsed_query) self.assertIn('Signature', parsed_query) self.assertIn('http://relaystate.com', parsed_query['RelayState']) self.assertIn(OneLogin_Saml2_Constants.RSA_SHA1, parsed_query['SigAlg'])
def testProcessSLORequestSignedResponse(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Request, validating the relayState, a signed LogoutResponse is created and a redirection executed """ settings_info = self.loadSettingsJSON() settings_info['security']['logoutResponseSigned'] = True request_data = self.get_request() message = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_deflated.xml.base64')) # In order to avoid the destination problem plain_message = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLRequest'] = message request_data['get_data']['RelayState'] = 'http://relaystate.com' auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info) auth.set_strict(True) target_url = auth.process_slo(False) parsed_query = parse_qs(urlparse(target_url)[4]) slo_url = settings_info['idp']['singleLogoutService']['url'] self.assertIn(slo_url, target_url) self.assertIn('SAMLResponse', parsed_query) self.assertIn('RelayState', parsed_query) self.assertIn('SigAlg', parsed_query) self.assertIn('Signature', parsed_query) self.assertIn('http://relaystate.com', parsed_query['RelayState']) self.assertIn(OneLogin_Saml2_Constants.RSA_SHA1, parsed_query['SigAlg'])
def testProcessSLOResponseValidDeletingSession(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Response, validating deleting the local session """ request_data = self.get_request() message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) # FIXME # if (!isset($_SESSION)) { # $_SESSION = array(); # } # $_SESSION['samltest'] = true; # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLResponse'] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) auth.set_strict(True) auth.process_slo(False) self.assertEqual(len(auth.get_errors()), 0)
def testIsInValidDestination(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse Case invalid Destination """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents( join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) settings.set_strict(False) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) try: valid = response_2.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The LogoutRequest was received at', str(e)) # Empty destination dom = parseString( OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) dom.firstChild.setAttribute('Destination', '') xml = dom.toxml() message_3 = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) response_3 = OneLogin_Saml2_Logout_Response(settings, message_3) self.assertTrue(response_3.is_valid(request_data)) # No destination dom.firstChild.removeAttribute('Destination') xml = dom.toxml() message_4 = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) response_4 = OneLogin_Saml2_Logout_Response(settings, message_4) self.assertTrue(response_4.is_valid(request_data))
def test_sls(self): """Test standard logout.""" self.client.force_login(self.user) self.assertEqual(int(self.client.session['_auth_user_id']), self.user.id) xml = _file_contents(os.path.join(data_directory, 'logout_response.xml')) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) url = reverse('django_saml:sls') + '?SAMLResponse=' + quote(message) response = self.client.get(url, HTTP_HOST='127.0.0.1') self.assertEqual(response.status_code, 302) self.assertEqual(response['Location'], '/logged-out') self.assertIsNone(self.client.session.get('_auth_user_id'))
def test_unknown_exception(self, mock): """Test that unknown exceptions are handled gracefully.""" logging.disable(logging.CRITICAL) logging.disable(logging.ERROR) mock.side_effect = Exception('Test exception') xml = _file_contents(os.path.join(data_directory, 'logout_response.xml')) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) url = reverse('django_saml:sls') + '?SAMLResponse=' + quote(message) response = self.client.get(url, HTTP_HOST='127.0.0.1') self.assertEqual(response.status_code, 400) self.assertEqual(response.content.decode(), 'Invalid request') logging.disable(logging.NOTSET)
def get_response(self, deflate=True): """ Returns the Logout Response defated, base64encoded :param deflate: It makes the deflate process optional :type: bool :return: Logout Response maybe deflated and base64 encoded :rtype: string """ if deflate: response = OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__logout_response) else: response = b64encode(self.__logout_response) return response
def get_request(self, deflate=True): """ Returns the Logout Request deflated, base64encoded :param deflate: It makes the deflate process optional :type: bool :return: Logout Request maybe deflated and base64 encoded :rtype: str object """ if deflate: request = OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__logout_request) else: request = OneLogin_Saml2_Utils.b64encode(self.__logout_request) return request
def get_request(self, deflate=True): """ Returns the Logout Request deflated, base64encoded :param deflate: It makes the deflate process optional :type: bool :return: Logout Request maybe deflated and base64 encoded :rtype: str object """ if deflate: request = OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__logout_request) else: request = b64encode(self.__logout_request) return request
def get_request(self, deflate=True): """ Returns unsigned AuthnRequest. :param deflate: It makes the deflate process optional :type: bool :return: AuthnRequest maybe deflated and base64 encoded :rtype: str object """ if deflate: request = OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__authn_request) else: request = b64encode(self.__authn_request) return request
def testIsInValidDestination(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse Case invalid Destination """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) settings.set_strict(False) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) try: valid = response_2.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The LogoutRequest was received at', e.message) # Empty destination dom = parseString(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) dom.firstChild.setAttribute('Destination', '') xml = dom.toxml() message_3 = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) response_3 = OneLogin_Saml2_Logout_Response(settings, message_3) self.assertTrue(response_3.is_valid(request_data)) # No destination dom.firstChild.removeAttribute('Destination') xml = dom.toxml() message_4 = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) response_4 = OneLogin_Saml2_Logout_Response(settings, message_4) self.assertTrue(response_4.is_valid(request_data))
def get_request(self, deflate=True): """ Returns unsigned AuthnRequest. :param deflate: It makes the deflate process optional :type: bool :return: AuthnRequest maybe deflated and base64 encoded :rtype: str object """ if deflate: request = OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__authn_request) else: request = OneLogin_Saml2_Utils.b64encode(self.__authn_request) return request
def get_request(self, deflate=None): """ Returns unsigned AuthnRequest. :param deflate: It makes the deflate process optional :type: bool :return: AuthnRequest maybe deflated and base64 encoded :rtype: str object """ if deflate or getattr(settings, 'ENABLE_SAML_COMPRESSION', True): request = OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__authn_request) else: request = b64encode(self.__authn_request) return request
def test_suomifi_logout_sp_response_invalid_relaystate(django_client): create_oidc_client() saml_response = load_file('suomifi_logout_response.xml') args = { 'SAMLResponse': SAMLUtils.deflate_and_base64_encode(saml_response), 'RelayState': 'INVALID', 'SigAlg': 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', 'Signature': load_file('suomifi_logout_response_with_invalid_relaystate_signature.b64').decode() } callback_url = reverse('auth_backends:suomifi_logout_callback') + '?{}'.format(urlencode(args)) callback_response = django_client.get(callback_url) # If RelayState in the logout response is invalid the user is redirected to LOGIN_URL assert callback_response.status_code == 302 assert urlparse(callback_response.url).path == getattr(settings, 'LOGIN_URL')
def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self): request = OneLogin_Saml2_Utils.deflate_and_base64_encode('<xml>invalid</xml>') request_data = { 'http_host': 'example.com', 'script_name': 'index.html' } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) settings.set_strict(True) logout_request = OneLogin_Saml2_Logout_Request(settings, request) self.assertFalse(logout_request.is_valid(request_data)) with self.assertRaisesRegexp(OneLogin_Saml2_ValidationError, "Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd"): logout_request.is_valid(request_data, raise_exceptions=True)
def test_suomifi_logout_sp_response(django_client): '''Suomi.fi use case #5: receiving logout response''' create_oidc_client() saml_response = load_file('suomifi_logout_response.xml') args = { 'SAMLResponse': SAMLUtils.deflate_and_base64_encode(saml_response), 'RelayState': '{"cli": "test_client", "idx": 0}', 'SigAlg': 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', 'Signature': load_file('suomifi_logout_response_signature.b64').decode() } callback_url = reverse('auth_backends:suomifi_logout_callback') + '?{}'.format(urlencode(args)) callback_response = django_client.get(callback_url) # After handling the logout response the user is redirected to REDIRECT_URI assert callback_response.status_code == 302 assert callback_response.url == REDIRECT_URI
def test_sls_invalid_saml(self): """Test catching SAML exceptions.""" # Purely so the exception logging doesn't get printed to the test console logging.disable(logging.CRITICAL) logging.disable(logging.ERROR) self.client.force_login(self.user) self.assertEqual(int(self.client.session['_auth_user_id']), self.user.id) xml = _file_contents(os.path.join(data_directory, 'logout_response.xml')) xml = xml.replace('http://127.0.0.1/saml/sls', 'example.com') message = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) url = reverse('django_saml:sls') + '?SAMLResponse=' + quote(message) response = self.client.get(url, HTTP_HOST='127.0.0.1') self.assertEqual(response.status_code, 400) self.assertEqual(response.content.decode(), 'Invalid request') # Put logging back the way we found it logging.disable(logging.NOTSET)
def testGetStatus(self): """ Tests the get_status method of the OneLogin_Saml2_LogoutResponse """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) status = response.get_status() self.assertEquals(status, OneLogin_Saml2_Constants.STATUS_SUCCESS) dom = parseString(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) status_code_node = dom.getElementsByTagName('samlp:StatusCode')[0] status_code_node.parentNode.removeChild(status_code_node) xml = dom.toxml() message_2 = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) response_2 = OneLogin_Saml2_Logout_Response(settings, message_2) self.assertIsNone(response_2.get_status())
def testProcessSLORequestDeletingSession(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Request, validating that the local session is deleted, a LogoutResponse is created and a redirection executed """ settings_info = self.loadSettingsJSON() request_data = self.get_request() message = self.file_contents( join(self.data_path, 'logout_requests', 'logout_request_deflated.xml.base64')) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace( 'http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLRequest'] = message # FIXME # if (!isset($_SESSION)) { # $_SESSION = array(); # } # $_SESSION['samltest'] = true; auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info) auth.set_strict(True) target_url = auth.process_slo(True) parsed_query = parse_qs(urlparse(target_url)[4]) slo_url = settings_info['idp']['singleLogoutService']['url'] self.assertIn(slo_url, target_url) self.assertIn('SAMLResponse', parsed_query) self.assertNotIn('RelayState', parsed_query) # FIXME // Session is not alive # $this->assertFalse(isset($_SESSION['samltest'])); # $_SESSION['samltest'] = true; auth.set_strict(True) target_url_2 = auth.process_slo(True) target_url_2 = auth.process_slo(True) parsed_query_2 = parse_qs(urlparse(target_url_2)[4]) slo_url = settings_info['idp']['singleLogoutService']['url'] self.assertIn(slo_url, target_url_2) self.assertIn('SAMLResponse', parsed_query_2) self.assertNotIn('RelayState', parsed_query_2)
def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self): message = OneLogin_Saml2_Utils.deflate_and_base64_encode( '<xml>invalid</xml>') request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) settings.set_strict(True) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertFalse(response.is_valid(request_data)) with self.assertRaises(Exception): response.is_valid(request_data, raise_exceptions=True)
def testProcessSLORequestNotOnOrAfterFailed(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Logout Request NotOnOrAfter failed """ request_data = self.get_request() message = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'not_after_failed.xml.base64')) # In order to avoid the destination problem plain_message = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLRequest'] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) auth.set_strict(True) auth.process_slo(True) self.assertEqual(auth.get_errors(), ['invalid_logout_request'])
def testProcessSLORequestNotOnOrAfterFailed(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Logout Request NotOnOrAfter failed """ request_data = self.get_request() message = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'not_after_failed.xml.base64')) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLRequest'] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) auth.set_strict(True) auth.process_slo(True) self.assertEqual(auth.get_errors(), ['invalid_logout_request'])
def testGetIssuer(self): """ Tests the get_issuer of the OneLogin_Saml2_LogoutResponse """ settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) response = OneLogin_Saml2_Logout_Response(settings, message) issuer = response.get_issuer() self.assertEquals('http://idp.example.com/', issuer) dom = parseString(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) issuer_node = dom.getElementsByTagName('saml:Issuer')[0] issuer_node.parentNode.removeChild(issuer_node) xml = dom.toxml() message_2 = OneLogin_Saml2_Utils.deflate_and_base64_encode(xml) response_2 = OneLogin_Saml2_Logout_Response(settings, message_2) issuer_2 = response_2.get_issuer() self.assertIsNone(issuer_2)
def testProcessSLORequestDeletingSession(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Valid Logout Request, validating that the local session is deleted, a LogoutResponse is created and a redirection executed """ settings_info = self.loadSettingsJSON() request_data = self.get_request() message = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request_deflated.xml.base64')) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLRequest'] = message # FIXME # if (!isset($_SESSION)) { # $_SESSION = array(); # } # $_SESSION['samltest'] = true; auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info) auth.set_strict(True) target_url = auth.process_slo(True) parsed_query = parse_qs(urlparse(target_url)[4]) slo_url = settings_info['idp']['singleLogoutService']['url'] self.assertIn(slo_url, target_url) self.assertIn('SAMLResponse', parsed_query) self.assertNotIn('RelayState', parsed_query) # FIXME // Session is not alive # $this->assertFalse(isset($_SESSION['samltest'])); # $_SESSION['samltest'] = true; auth.set_strict(True) target_url_2 = auth.process_slo(True) target_url_2 = auth.process_slo(True) parsed_query_2 = parse_qs(urlparse(target_url_2)[4]) slo_url = settings_info['idp']['singleLogoutService']['url'] self.assertIn(slo_url, target_url_2) self.assertIn('SAMLResponse', parsed_query_2) self.assertNotIn('RelayState', parsed_query_2)
def testIsInvalidXML(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse Case Invalid XML """ message = OneLogin_Saml2_Utils.deflate_and_base64_encode('<xml>invalid</xml>') request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) response = OneLogin_Saml2_Logout_Response(settings, message) self.assertTrue(response.is_valid(request_data)) settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, message) self.assertFalse(response_2.is_valid(request_data))
def testProcessSLOResponseNoSucess(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Logout Response not sucess """ request_data = self.get_request() message = self.file_contents( join(self.data_path, "logout_responses", "invalids", "status_code_responder.xml.base64") ) # In order to avoid the destination problem plain_message = OneLogin_Saml2_Utils.decode_base64_and_inflate(message) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace("http://stuff.com/endpoints/endpoints/sls.php", current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data["get_data"]["SAMLResponse"] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) auth.set_strict(True) auth.process_slo(True) self.assertEqual(auth.get_errors(), ["logout_not_success"])
def modify_start_url(self, start_url): """ Given a SAML redirect URL, parse it and change the ID to a consistent value, so the request is always identical. """ # Parse the SAML Request URL to get the XML being sent to TestShib url_parts = urlparse(start_url) query = dict( (k, v[0]) for (k, v) in parse_qs(url_parts.query).iteritems()) xml = OneLogin_Saml2_Utils.decode_base64_and_inflate( query['SAMLRequest']) # Modify the XML: xml, changed = re.subn(r'ID="[^"]+"', 'ID="TEST_ID"', xml) self.assertEqual(changed, 1) # Update the URL to use the modified query string: query['SAMLRequest'] = OneLogin_Saml2_Utils.deflate_and_base64_encode( xml) url_parts = list(url_parts) url_parts[4] = urlencode(query) return urlunparse(url_parts)
def modify_start_url(self, start_url): """ Given a SAML redirect URL, parse it and change the ID to a consistent value, so the request is always identical. """ # Parse the SAML Request URL to get the XML being sent to TestShib url_parts = urlparse(start_url) query = dict((k, v[0]) for (k, v) in parse_qs(url_parts.query).iteritems()) xml = OneLogin_Saml2_Utils.decode_base64_and_inflate( query['SAMLRequest'] ) # Modify the XML: xml, changed = re.subn(r'ID="[^"]+"', 'ID="TEST_ID"', xml) self.assertEqual(changed, 1) # Update the URL to use the modified query string: query['SAMLRequest'] = OneLogin_Saml2_Utils.deflate_and_base64_encode( xml ) url_parts = list(url_parts) url_parts[4] = urlencode(query) return urlunparse(url_parts)
def testProcessSLOResponseRequestId(self): """ Tests the process_slo method of the OneLogin_Saml2_Auth class Case Logout Response with valid and invalid Request ID """ request_data = self.get_request() message = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response_deflated.xml.base64')) # In order to avoid the destination problem plain_message = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(message)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message = plain_message.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) message = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message) request_data['get_data']['SAMLResponse'] = message auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON()) request_id = 'wrongID' auth.set_strict(True) auth.process_slo(True, request_id) self.assertEqual(auth.get_errors(), ['invalid_logout_response']) request_id = 'ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e' auth.process_slo(True, request_id) self.assertEqual(len(auth.get_errors()), 0)
def testGetXML(self): """ Tests that we can get the logout response XML directly without going through intermediate steps """ response = self.file_contents(join(self.data_path, 'logout_responses', 'logout_response.xml')) settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) logout_response_generated = OneLogin_Saml2_Logout_Response(settings) logout_response_generated.build("InResponseValue") expectedFragment = ( 'Destination="http://idp.example.com/SingleLogoutService.php"\n' ' InResponseTo="InResponseValue"\n>\n' ' <saml:Issuer>http://stuff.com/endpoints/metadata.php</saml:Issuer>\n' ' <samlp:Status>\n' ' <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />\n' ' </samlp:Status>\n' '</samlp:LogoutResponse>' ) self.assertIn(expectedFragment, logout_response_generated.get_xml()) logout_response_processed = OneLogin_Saml2_Logout_Response(settings, OneLogin_Saml2_Utils.deflate_and_base64_encode(response)) self.assertEqual(response, logout_response_processed.get_xml())
def testIsValidLogoutRequestSign(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutRequest """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': { 'SAMLRequest': 'lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=', 'RelayState': '_1037fbc88ec82ce8e770b2bed1119747bb812a07e6', 'SigAlg': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1', 'Signature': 'XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc=' } } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) request = compat.to_string(OneLogin_Saml2_Utils.decode_base64_and_inflate(request_data['get_data']['SAMLRequest'])) settings.set_strict(False) auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertEqual([], auth.get_errors()) relay_state = request_data['get_data']['RelayState'] del request_data['get_data']['RelayState'] auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('invalid_logout_request_signature', auth.get_errors()) request_data['get_data']['RelayState'] = relay_state settings.set_strict(True) auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('invalid_logout_request', auth.get_errors()) settings.set_strict(False) old_signature = request_data['get_data']['Signature'] request_data['get_data']['Signature'] = 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333=' auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('invalid_logout_request_signature', auth.get_errors()) request_data['get_data']['Signature'] = old_signature old_signature_algorithm = request_data['get_data']['SigAlg'] del request_data['get_data']['SigAlg'] auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertEqual([], auth.get_errors()) settings.set_strict(True) request_2 = request.replace('https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls', current_url) request_2 = request_2.replace('https://pitbulk.no-ip.org/simplesaml/saml2/idp/metadata.php', 'http://idp.example.com/') request_data['get_data']['SAMLRequest'] = OneLogin_Saml2_Utils.deflate_and_base64_encode(request_2) auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('invalid_logout_request_signature', auth.get_errors()) settings.set_strict(False) auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('invalid_logout_request_signature', auth.get_errors()) request_data['get_data']['SigAlg'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1' auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('invalid_logout_request_signature', auth.get_errors()) settings_info = self.loadSettingsJSON() settings_info['strict'] = True settings_info['security']['wantMessagesSigned'] = True settings = OneLogin_Saml2_Settings(settings_info) request_data['get_data']['SigAlg'] = old_signature_algorithm old_signature = request_data['get_data']['Signature'] del request_data['get_data']['Signature'] auth = OneLogin_Saml2_Auth(request_data, old_settings=settings) auth.process_slo() self.assertIn('Signature validation failed. Logout Request rejected', auth.get_errors()) request_data['get_data']['Signature'] = old_signature settings_info['idp']['certFingerprint'] = 'afe71c28ef740bc87425be13a2263d37971da1f9' del settings_info['idp']['x509cert'] settings_2 = OneLogin_Saml2_Settings(settings_info) auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_2) auth.process_slo() self.assertIn('In order to validate the sign on the SAMLRequest, the x509cert of the IdP is required', auth.get_errors())
def testIsInValidSign(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutResponse """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', 'get_data': {} } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) settings.set_strict(False) request_data['get_data'] = { 'SAMLResponse': 'fZJva8IwEMa/Ssl7TZrW/gnqGHMMwSlM8cXeyLU9NaxNQi9lfvxVZczB5ptwSe733MPdjQma2qmFPdjOvyE5awiDU1MbUpevCetaoyyQJmWgQVK+VOvH14WSQ6Fca70tbc1ukPsEEGHrtTUsmM8mbDfKUhnFci8gliGINI/yXIAAiYnsw6JIRgWWAKlkwRZb6skJ64V6nKjDuSEPxvdPIowHIhpIsQkTFaYqSt9ZMEPy2oC/UEfvHSnOnfZFV38MjR1oN7TtgRv8tAZre9CGV9jYkGtT4Wnoju6Bauprme/ebOyErZbPi9XLfLnDoohwhHGc5WVSVhjCKM6rBMpYQpWJrIizfZ4IZNPxuTPqYrmd/m+EdONqPOfy8yG5rhxv0EMFHs52xvxWaHyd3tqD7+j37clWGGyh7vD+POiSrdZdWSIR49NrhR9R/teGTL8A', 'RelayState': 'https://pitbulk.no-ip.org/newonelogin/demo1/index.php', 'SigAlg': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1', 'Signature': 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVfNKGA=' } response = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) self.assertTrue(response.is_valid(request_data)) relayState = request_data['get_data']['RelayState'] del request_data['get_data']['RelayState'] inv_response = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) self.assertFalse(inv_response.is_valid(request_data)) request_data['get_data']['RelayState'] = relayState settings.set_strict(True) response_2 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_2.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Invalid issuer in the Logout Request', e.message) settings.set_strict(False) old_signature = request_data['get_data']['Signature'] request_data['get_data']['Signature'] = 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333=' response_3 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_3.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Response rejected', e.message) request_data['get_data']['Signature'] = old_signature old_signature_algorithm = request_data['get_data']['SigAlg'] del request_data['get_data']['SigAlg'] response_4 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) self.assertTrue(response_4.is_valid(request_data)) request_data['get_data']['RelayState'] = 'http://example.com/relaystate' response_5 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_5.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Response rejected', e.message) settings.set_strict(True) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) plain_message_6 = OneLogin_Saml2_Utils.decode_base64_and_inflate(request_data['get_data']['SAMLResponse']) plain_message_6 = plain_message_6.replace('https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls', current_url) plain_message_6 = plain_message_6.replace('https://pitbulk.no-ip.org/simplesaml/saml2/idp/metadata.php', 'http://idp.example.com/') request_data['get_data']['SAMLResponse'] = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message_6) response_6 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_6.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Response rejected', e.message) settings.set_strict(False) response_7 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_7.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Response rejected', e.message) request_data['get_data']['SigAlg'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1' response_8 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_8.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Invalid signAlg in the recieved Logout Response', e.message) settings_info = self.loadSettingsJSON() settings_info['strict'] = True settings_info['security']['wantMessagesSigned'] = True settings = OneLogin_Saml2_Settings(settings_info) request_data['get_data']['SigAlg'] = old_signature_algorithm old_signature = request_data['get_data']['Signature'] del request_data['get_data']['Signature'] request_data['get_data']['SAMLResponse'] = OneLogin_Saml2_Utils.deflate_and_base64_encode(plain_message_6) response_9 = OneLogin_Saml2_Logout_Response(settings, request_data['get_data']['SAMLResponse']) try: valid = response_9.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The Message of the Logout Response is not signed and the SP require it', e.message) request_data['get_data']['Signature'] = old_signature settings_info['idp']['certFingerprint'] = 'afe71c28ef740bc87425be13a2263d37971da1f9' del settings_info['idp']['x509cert'] settings_2 = OneLogin_Saml2_Settings(settings_info) response_10 = OneLogin_Saml2_Logout_Response(settings_2, request_data['get_data']['SAMLResponse']) try: valid = response_10.is_valid(request_data) self.assertFalse(valid) except Exception as e: self.assertIn('In order to validate the sign on the Logout Response, the x509cert of the IdP is required', e.message)