/**
  * Handle the forwarding of the user to the proper IdP0 after the WAYF screen.
  *
  * @param string $serviceName
  * @throws EngineBlock_Corto_Module_Services_Exception
  * @throws EngineBlock_Exception
  * @throws EngineBlock_Corto_Module_Services_SessionLostException
  */
 public function serve($serviceName)
 {
     $selectedIdp = urldecode($_REQUEST['idp']);
     if (!$selectedIdp) {
         throw new EngineBlock_Corto_Module_Services_Exception('No IdP selected after WAYF');
     }
     // Retrieve the request from the session.
     $id = $_POST['ID'];
     if (!$id) {
         throw new EngineBlock_Exception('Missing ID for AuthnRequest after WAYF', EngineBlock_Exception::CODE_NOTICE);
     }
     $authnRequestRepository = new EngineBlock_Saml2_AuthnRequestSessionRepository($this->_server->getSessionLog());
     $request = $authnRequestRepository->findRequestById($id);
     if (!$request) {
         throw new EngineBlock_Corto_Module_Services_SessionLostException('Session lost after WAYF');
     }
     // Flush log if SP or IdP has additional logging enabled
     $sp = $this->_server->getRepository()->fetchServiceProviderByEntityId($request->getIssuer());
     $idp = $this->_server->getRepository()->fetchIdentityProviderByEntityId($selectedIdp);
     if (EngineBlock_SamlHelper::doRemoteEntitiesRequireAdditionalLogging(array($sp, $idp))) {
         $application = EngineBlock_ApplicationSingleton::getInstance();
         $application->flushLog('Activated additional logging for the SP or IdP');
         $log = $application->getLogInstance();
         $log->info('Raw HTTP request', array('http_request' => (string) $application->getHttpRequest()));
     }
     $this->_server->sendAuthenticationRequest($request, $selectedIdp);
 }
 /**
  * @param EngineBlock_Saml2_ResponseAnnotationDecorator $response
  * @return EngineBlock_Saml2_AuthnRequestAnnotationDecorator
  * @throws EngineBlock_Corto_ProxyServer_Exception
  * @throws EngineBlock_Exception
  * @throws EngineBlock_Corto_Module_Services_SessionLostException
  */
 public function getReceivedRequestFromResponse(EngineBlock_Saml2_ResponseAnnotationDecorator $response)
 {
     /** @var SAML2_Response $response */
     $requestId = $response->getInResponseTo();
     if (!$requestId) {
         throw new EngineBlock_Corto_ProxyServer_Exception('Response without InResponseTo, e.g. unsolicited. We don\'t support this.', EngineBlock_Exception::CODE_NOTICE);
     }
     $authnRequestRepository = new EngineBlock_Saml2_AuthnRequestSessionRepository($this->getSessionLog());
     $spRequestId = $authnRequestRepository->findLinkedRequestId($requestId);
     if (!$spRequestId) {
         throw new EngineBlock_Corto_Module_Services_SessionLostException("Trying to find a AuthnRequest (we made and sent) with id '{$requestId}' but it is not known in this session? " . "This could be an unsolicited Response (which we do not support) but more likely the user lost their session", EngineBlock_Corto_ProxyServer_Exception::CODE_NOTICE);
     }
     $spRequest = $authnRequestRepository->findRequestById($spRequestId);
     if (!$spRequest) {
         throw new EngineBlock_Corto_ProxyServer_Exception('Response has no known Request', EngineBlock_Corto_ProxyServer_Exception::CODE_NOTICE);
     }
     return $spRequest;
 }