def testIsValid(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutRequest """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html' } request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml')) settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) settings.set_strict(True) self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) settings.set_strict(False) dom = parseString(request) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, dom, request_data)) settings.set_strict(True) self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, dom, request_data)) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) request_2 = request.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data))
def testIsInvalidDestination(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutRequest Case Invalid Destination """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html' } request = self.file_contents(join(self.data_path, 'logout_requests', 'logout_request.xml')) settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) settings.set_strict(True) try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The LogoutRequest was received at', e.message) dom = parseString(request) dom.documentElement.setAttribute('Destination', None) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, dom.toxml(), request_data)) dom.documentElement.removeAttribute('Destination') self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, dom.toxml(), request_data))
def testIsInvalidXML(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutRequest Case Invalid XML """ request = '<xml>invalid</xml>' request_data = { 'http_host': 'example.com', 'script_name': 'index.html' } settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) settings.set_strict(True) self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data))
def testIsInvalidNotOnOrAfter(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutRequest Case Invalid NotOnOrAfter """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html' } request = self.file_contents(join(self.data_path, 'logout_requests', 'invalids', 'not_after_failed.xml')) current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data) request = request.replace('http://stuff.com/endpoints/endpoints/sls.php', current_url) settings = OneLogin_Saml2_Settings(self.loadSettingsJSON()) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) settings.set_strict(True) try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Timing issues (please check your clock settings)', e.message)
def process_slo(self, keep_local_session=False, request_id=None, delete_session_cb=None): """ Process the SAML Logout Response / Logout Request sent by the IdP. :param keep_local_session: When false will destroy the local session, otherwise will destroy it :type keep_local_session: bool :param request_id: The ID of the LogoutRequest sent by this SP to the IdP :type request_id: string :returns: Redirection url """ self.__errors = [] if 'get_data' in self.__request_data and 'SAMLResponse' in self.__request_data['get_data']: logout_response = OneLogin_Saml2_Logout_Response(self.__settings, self.__request_data['get_data']['SAMLResponse']) if not logout_response.is_valid(self.__request_data, request_id): self.__errors.append('invalid_logout_response') elif logout_response.get_status() != OneLogin_Saml2_Constants.STATUS_SUCCESS: self.__errors.append('logout_not_success') elif not keep_local_session: OneLogin_Saml2_Utils.delete_local_session(delete_session_cb) elif 'get_data' in self.__request_data and 'SAMLRequest' in self.__request_data['get_data']: request = OneLogin_Saml2_Utils.decode_base64_and_inflate(self.__request_data['get_data']['SAMLRequest']) if not OneLogin_Saml2_Logout_Request.is_valid(self.__settings, request, self.__request_data): self.__errors.append('invalid_logout_request') else: if not keep_local_session: OneLogin_Saml2_Utils.delete_local_session(delete_session_cb) in_response_to = OneLogin_Saml2_Logout_Request.get_id(request) response_builder = OneLogin_Saml2_Logout_Response(self.__settings) response_builder.build(in_response_to) logout_response = response_builder.get_response() parameters = {'SAMLResponse': logout_response} if 'RelayState' in self.__request_data['get_data']: parameters['RelayState'] = self.__request_data['get_data']['RelayState'] security = self.__settings.get_security_data() if 'logoutResponseSigned' in security and security['logoutResponseSigned']: parameters['SigAlg'] = OneLogin_Saml2_Constants.RSA_SHA1 parameters['Signature'] = self.build_response_signature(logout_response, parameters.get('RelayState', None)) return self.redirect_to(self.get_slo_url(), parameters) else: self.__errors.append('invalid_binding') raise OneLogin_Saml2_Error( 'SAML LogoutRequest/LogoutResponse not found. Only supported HTTP_REDIRECT Binding', OneLogin_Saml2_Error.SAML_LOGOUTMESSAGE_NOT_FOUND )
def testIsValidSign(self): """ Tests the is_valid method of the OneLogin_Saml2_LogoutRequest """ request_data = { 'http_host': 'example.com', 'script_name': 'index.html', '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 = OneLogin_Saml2_Utils.decode_base64_and_inflate(request_data['SAMLRequest']) settings.set_strict(False) self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) relayState = request_data['RelayState'] del request_data['RelayState'] self.assertFalse(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) request_data['RelayState'] = relayState settings.set_strict(True) try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The LogoutRequest was received at', e.message) settings.set_strict(False) old_signature = request_data['Signature'] request_data['Signature'] = 'vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333=' try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Request rejected', e.message) request_data['Signature'] = old_signature old_signature_algorithm = request_data['SigAlg'] del request_data['SigAlg'] self.assertTrue(OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data)) request_data['RelayState'] = 'http://example.com/relaystate' try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Request rejected', e.message) 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['SAMLRequest'] = OneLogin_Saml2_Utils.deflate_and_base64_encode(request_2) try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Request rejected', e.message) settings.set_strict(False) try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Signature validation failed. Logout Request rejected', e.message) request_data['SigAlg'] = 'http://www.w3.org/2000/09/xmldsig#dsa-sha1' try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('Invalid signAlg in the recieved Logout Request', e.message) settings_info = self.loadSettingsJSON() settings_info['strict'] = True settings_info['security']['wantMessagesSigned'] = True settings = OneLogin_Saml2_Settings(settings_info) request_data['SigAlg'] = old_signature_algorithm old_signature = request_data['Signature'] del request_data['Signature'] try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings, request_2, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('The Message of the Logout Request is not signed and the SP require it', e.message) request_data['Signature'] = old_signature settings_info['idp']['certFingerprint'] = 'afe71c28ef740bc87425be13a2263d37971da1f9' del settings_info['idp']['x509cert'] settings_2 = OneLogin_Saml2_Settings(settings_info) try: valid = OneLogin_Saml2_Logout_Request.is_valid(settings_2, request_2, request_data) self.assertFalse(valid) except Exception as e: self.assertIn('In order to validate the sign on the Logout Request, the x509cert of the IdP is required', e.message)