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_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)
def test_verify_response_without_assertion(self): with cast(TextIO, (DATA_DIR / 'signed_failed_response.xml').open('r')) as f: tree = parse_xml(f.read()) remove_extra_xml_whitespace(tree) response = SAMLResponse(tree) response.verify_response(CERT_FILE)
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 post(self, request: HttpRequest) -> HttpResponse: """Handle a HTTP POST request.""" saml_response_xml = b64decode(self.request.POST.get('SAMLResponse', '').encode('ascii')).decode('utf-8') if saml_response_xml: # Verify signatures cert_file = (CONNECTOR_SETTINGS.service_provider['response_signature'] or {}).get('cert_file') if cert_file: response = SAMLResponse(parse_xml(saml_response_xml)) response.verify_response(cert_file) response.verify_assertion(cert_file) # Reformat with pretty printing for display saml_response_xml = dump_xml(parse_xml(saml_response_xml)).decode('utf-8') self.saml_response = saml_response_xml self.relay_state = self.request.POST.get('RelayState') return self.get(request)