'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'

def phase2(self, authn_request, rc_url, idp_entity_id, headers=None, sign=False, **kwargs):

    (_, destination) = self.pick_binding('single_sign_on_service', [BINDING_SOAP], 'idpsso', entity_id=idp_entity_id)
    ht_args = self.apply_binding(BINDING_SOAP, authn_request, destination, sign=sign)
    if headers:
        ht_args['headers'].extend(headers)
    logger.debug(('[P2]    Sending    request:    %s' % ht_args['data']))
    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)))
    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))
        _ = self.send(rc_url, 'POST', data=soap.soap_fault(error))
        raise SAMLError(error)
    return idp_response
