def phase2(self, authn_request, rc_url, idp_entity_id, headers=None, sign=False, **kwargs): """ Doing the second phase of the ECP conversation, the conversation with the IdP happens. :param authn_request: The AuthenticationRequest :param rc_url: The assertion consumer service url of the SP :param idp_entity_id: The EntityID of the IdP :param headers: Possible extra headers :param sign: If the message should be signed :return: The response from the IdP """ _, destination = self.pick_binding("single_sign_on_service", [BINDING_PAOS], "idpsso", entity_id=idp_entity_id) ht_args = self.apply_binding(BINDING_PAOS, authn_request, destination, sign=sign) if headers: ht_args["headers"].extend(headers) logger.debug("[P2] Sending request: %s" % ht_args["data"]) # POST the request to the IdP response = self.send(**ht_args) logger.debug("[P2] Got IdP response: %s" % response) if response.status_code != 200: raise SAMLError("Request to IdP failed (%s): %s" % (response.status_code, response.error)) # SAMLP response in a SOAP envelope body, ecp response in headers respdict = self.parse_soap_message(response.text) if respdict is None: raise SAMLError("Unexpected reply from the IdP") logger.debug("[P2] IdP response dict: %s" % respdict) idp_response = respdict["body"] assert idp_response.c_tag == "Response" logger.debug("[P2] IdP AUTHN response: %s" % idp_response) _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and item.c_namespace == ecp.NAMESPACE: _ecp_response = item _acs_url = _ecp_response.assertion_consumer_service_url if rc_url != _acs_url: error = ( "response_consumer_url '%s' does not match" % rc_url, "assertion_consumer_service_url '%s" % _acs_url, ) # Send an error message to the SP _ = self.send(rc_url, "POST", data=soap.soap_fault(error)) # Raise an exception so the user knows something went wrong raise SAMLError(error) return idp_response
def phase2(self, authn_request, rc_url, idp_entity_id, headers=None, sign=False, **kwargs): """ Doing the second phase of the ECP conversation, the conversation with the IdP happens. :param authn_request: The AuthenticationRequest :param rc_url: The assertion consumer service url of the SP :param idp_entity_id: The EntityID of the IdP :param headers: Possible extra headers :param sign: If the message should be signed :return: The response from the IdP """ _, destination = self.pick_binding("single_sign_on_service", [BINDING_PAOS], "idpsso", entity_id=idp_entity_id) ht_args = self.apply_binding(BINDING_PAOS, authn_request, destination, sign=sign) if headers: ht_args["headers"].extend(headers) logger.debug("[P2] Sending request: %s" % ht_args["data"]) # POST the request to the IdP response = self.send(**ht_args) logger.debug("[P2] Got IdP response: %s" % response) if response.status_code != 200: raise Exception("Request to IdP failed (%s): %s" % (response.status_code, response.error)) # SAMLP response in a SOAP envelope body, ecp response in headers respdict = self.parse_soap_message(response.text) if respdict is None: raise Exception("Unexpected reply from the IdP") logger.debug("[P2] IdP response dict: %s" % respdict) idp_response = respdict["body"] assert idp_response.c_tag == "Response" logger.debug("[P2] IdP AUTHN response: %s" % idp_response) _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and item.c_namespace == ecp.NAMESPACE: _ecp_response = item _acs_url = _ecp_response.assertion_consumer_service_url if rc_url != _acs_url: error = ("response_consumer_url '%s' does not match" % rc_url, "assertion_consumer_service_url '%s" % _acs_url) # Send an error message to the SP _ = self.send(rc_url, "POST", data=soap.soap_fault(error)) # Raise an exception so the user knows something went wrong raise Exception(error) return idp_response
def phase2(self, authn_request, rc_url, idp_entity_id, headers=None, idp_endpoint=None, sign=False, sec=""): """ Doing the second phase of the ECP conversation :param authn_request: The AuthenticationRequest :param rc_url: The assertion consumer service url :param idp_entity_id: The EntityID of the IdP :param headers: Possible extra headers :param idp_endpoint: Where to send it all :param sign: If the message should be signed :param sec: security context :return: The response from the IdP """ idp_request = soap.make_soap_enveloped_saml_thingy(authn_request) if sign: _signed = sec.sign_statement_using_xmlsec(idp_request, class_name(authn_request), nodeid=authn_request.id) idp_request = _signed if not idp_endpoint: idp_endpoint = self.find_idp_endpoint(idp_entity_id) if self.user and self.passwd: self.http.add_credentials(self.user, self.passwd) self._debug_info("[P2] Sending request: %s" % idp_request) # POST the request to the IdP response = self.http.post(idp_request, headers=headers, path=idp_endpoint) self._debug_info("[P2] Got IdP response: %s" % response) if response is None or response is False: raise Exception( "Request to IdP failed (%s): %s" % (self.http.response.status, self.http.error_description)) # SAMLP response in a SOAP envelope body, ecp response in headers respdict = soap.class_instances_from_soap_enveloped_saml_thingies( response, [paos, ecp,samlp]) if respdict is None: raise Exception("Unexpected reply from the IdP") self._debug_info("[P2] IdP response dict: %s" % respdict) idp_response = respdict["body"] assert idp_response.c_tag == "Response" self._debug_info("[P2] IdP AUTHN response: %s" % idp_response) _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and\ item.c_namespace == ecp.NAMESPACE: _ecp_response = item _acs_url = _ecp_response.assertion_consumer_service_url if rc_url != _acs_url: error = ("response_consumer_url '%s' does not match" % rc_url, "assertion_consumer_service_url '%s" % _acs_url) # Send an error message to the SP fault_text = soap.soap_fault(error) _ = self.http.post(fault_text, path=rc_url) # Raise an exception so the user knows something went wrong raise Exception(error) return idp_response
def phase2(self, authn_request, rc_url, idp_entity_id, headers=None, idp_endpoint=None, sign=False, sec=""): """ Doing the second phase of the ECP conversation :param authn_request: The AuthenticationRequest :param rc_url: The assertion consumer service url :param idp_entity_id: The EntityID of the IdP :param headers: Possible extra headers :param idp_endpoint: Where to send it all :param sign: If the message should be signed :param sec: security context :return: The response from the IdP """ idp_request = soap.make_soap_enveloped_saml_thingy(authn_request) if sign: _signed = sec.sign_statement_using_xmlsec( idp_request, class_name(authn_request), nodeid=authn_request.id) idp_request = _signed if not idp_endpoint: idp_endpoint = self.find_idp_endpoint(idp_entity_id) if self.user and self.passwd: self.http.add_credentials(self.user, self.passwd) self._debug_info("[P2] Sending request: %s" % idp_request) # POST the request to the IdP response = self.http.post(idp_request, headers=headers, path=idp_endpoint) self._debug_info("[P2] Got IdP response: %s" % response) if response is None or response is False: raise Exception( "Request to IdP failed (%s): %s" % (self.http.response.status, self.http.error_description)) # SAMLP response in a SOAP envelope body, ecp response in headers respdict = soap.class_instances_from_soap_enveloped_saml_thingies( response, [paos, ecp, samlp]) if respdict is None: raise Exception("Unexpected reply from the IdP") self._debug_info("[P2] IdP response dict: %s" % respdict) idp_response = respdict["body"] assert idp_response.c_tag == "Response" self._debug_info("[P2] IdP AUTHN response: %s" % idp_response) _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and\ item.c_namespace == ecp.NAMESPACE: _ecp_response = item _acs_url = _ecp_response.assertion_consumer_service_url if rc_url != _acs_url: error = ("response_consumer_url '%s' does not match" % rc_url, "assertion_consumer_service_url '%s" % _acs_url) # Send an error message to the SP fault_text = soap.soap_fault(error) _ = self.http.post(fault_text, path=rc_url) # Raise an exception so the user knows something went wrong raise Exception(error) return idp_response