def get_saml_response(self, key_file: Optional[str], cert_file: Optional[str]) -> SAMLResponse: """ Extract and decrypt a SAML response from POST data. :param key_file: An optional path to a key to decrypt the response. :param cert_file: An optional path to a certificate to verify the response. :return: A SAML response. """ raw_response = b64decode( self.request.POST.get('SAMLResponse', '').encode('ascii')).decode('utf-8') LOGGER.debug('Raw SAML Response: %s', raw_response) try: response = SAMLResponse(parse_xml(raw_response), self.request.POST.get('RelayState')) except XMLSyntaxError as e: raise ParseError(str(e)) from None LOGGER.info( '[#%r] Received SAML response: id=%r, issuer=%r, in_response_to_id=%r', self.log_id, response.id, response.issuer, response.in_response_to_id) if cert_file: response.verify_response(cert_file) if key_file: response.decrypt(key_file) if cert_file: response.verify_assertion(cert_file) return response
def test_verify_response_and_assertion_nia(self): with cast(TextIO, (DATA_DIR / 'nia_test_response.xml').open('r')) as f: tree = parse_xml(f.read()) remove_extra_xml_whitespace(tree) response = SAMLResponse(tree) response.verify_response(NIA_CERT_FILE) response.decrypt(KEY_FILE) self.assertTrue(response.verify_assertion(NIA_CERT_FILE))
def test_decrypt(self): self.maxDiff = None with cast(BinaryIO, (DATA_DIR / 'saml_response_decrypted.xml').open('rb')) as f: document_decrypted = f.read() with cast(BinaryIO, (DATA_DIR / 'saml_response_encrypted.xml').open('rb')) as f: document_encrypted = f.read() response = SAMLResponse(parse_xml(document_encrypted)) self.assertEqual(response.decrypt(KEY_FILE), 1) self.assertXMLEqual( dump_xml(response.document).decode('utf-8'), document_decrypted.decode('utf-8'))
def test_encrypt_assertion_without_encrypted_assertion_elm(self): root = Element(Q_NAMES['saml2p:Response']) first_child = SubElement(root, 'FirstChild') assertion = SubElement(root, Q_NAMES['saml2:Assertion']) SubElement(assertion, Q_NAMES['saml2:Issuer']).text = 'CZ.NIC' third_child = SubElement(root, 'ThirdChild') response = SAMLResponse((ElementTree(root))) # Encryption happened. self.assertTrue( response.encrypt_assertion(CERT_FILE, XmlBlockCipher.AES256_CBC, XmlKeyTransport.RSA_OAEP_MGF1P)) # Order of elements kept. self.assertIs(root[0], first_child) self.assertIs(root[2], third_child) # <Assertion> replaced with <EncryptedAssertion>. self.assertEqual(root[1].tag, Q_NAMES['saml2:EncryptedAssertion']) self.assertEqual(root[1][0].tag, Q_NAMES['xmlenc:EncryptedData']) # Make sure we can decrypt the result. self.assertEqual(response.decrypt(KEY_FILE), 1)