示例#1
0
    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())
示例#2
0
    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)
示例#4
0
    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)
示例#5
0
    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))
示例#7
0
    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)
示例#8
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))
示例#9
0
 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)
示例#10
0
 def get_request(self):
     """
     Returns unsigned AuthnRequest.
     :return: Unsigned AuthnRequest
     :rtype: str object
     """
     return OneLogin_Saml2_Utils.deflate_and_base64_encode(self.__authn_request)
示例#11
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 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())
示例#13
0
    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"])
示例#14
0
    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))
示例#15
0
 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_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 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))
示例#18
0
    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))
示例#19
0
    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'])
示例#20
0
    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'])
示例#21
0
    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)
示例#22
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))
示例#23
0
 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'))
示例#24
0
 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)
示例#25
0
 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
示例#26
0
 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
示例#27
0
 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
示例#28
0
 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_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
示例#31
0
 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
示例#32
0
    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
示例#33
0
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')
示例#34
0
    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 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_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 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
示例#38
0
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
示例#39
0
 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())
示例#41
0
    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())
示例#42
0
    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)
示例#43
0
    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)
示例#44
0
    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'])
示例#45
0
    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)
示例#47
0
    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))
示例#49
0
    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)
示例#50
0
    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))
示例#51
0
    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"])
示例#52
0
 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)
示例#53
0
文件: test_saml.py 项目: 2070616d/TP3
 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)
示例#54
0
    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())
示例#56
0
    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)