public static function createFromRequest(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $originalRequest, IdentityProvider $idpMetadata, EngineBlock_Corto_ProxyServer $server)
 {
     $nameIdPolicy = array('AllowCreate' => 'true');
     /**
      * Name policy is not required, so it is only set if configured, SAML 2.0 spec
      * says only following values are allowed:
      *  - urn:oasis:names:tc:SAML:2.0:nameid-format:transient
      *  - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent.
      *
      * Note: Some IDP's like those using ADFS2 do not understand those, for these cases the format can be 'configured as empty
      * or set to an older version.
      */
     if (!empty($idpMetadata->nameIdFormat)) {
         $nameIdPolicy['Format'] = $idpMetadata->nameIdFormat;
     }
     /** @var SAML2_AuthnRequest $originalRequest */
     $sspRequest = new SAML2_AuthnRequest();
     $sspRequest->setId($server->getNewId(\OpenConext\Component\EngineBlockFixtures\IdFrame::ID_USAGE_SAML2_REQUEST));
     $sspRequest->setIssueInstant(time());
     $sspRequest->setDestination($idpMetadata->singleSignOnServices[0]->location);
     $sspRequest->setForceAuthn($originalRequest->getForceAuthn());
     $sspRequest->setIsPassive($originalRequest->getIsPassive());
     $sspRequest->setAssertionConsumerServiceURL($server->getUrl('assertionConsumerService'));
     $sspRequest->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST);
     $sspRequest->setIssuer($server->getUrl('spMetadataService'));
     $sspRequest->setNameIdPolicy($nameIdPolicy);
     if (empty($idpMetadata->disableScoping)) {
         // Copy over the Idps that are allowed to answer this request.
         $sspRequest->setIDPList($originalRequest->getIDPList());
         // Proxy Count
         $sspRequest->setProxyCount($originalRequest->getProxyCount() ? $originalRequest->getProxyCount() : $server->getConfig('max_proxies', 10));
         // Add the SP to the requesterIds
         $requesterIds = $originalRequest->getRequesterID();
         $requesterIds[] = $originalRequest->getIssuer();
         // Add the SP as the requester
         $sspRequest->setRequesterID($requesterIds);
     }
     // Use the default binding even if more exist
     $request = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($sspRequest);
     $request->setDeliverByBinding($idpMetadata->singleSignOnServices[0]->binding);
     return $request;
 }
 protected function _sendCachedResponse(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $request, $scopedIdps)
 {
     /** @var SAML2_AuthnRequest $request */
     if ($request->getForceAuthn()) {
         return false;
     }
     if (!isset($_SESSION['CachedResponses'])) {
         return false;
     }
     $cachedResponses = $_SESSION['CachedResponses'];
     $requestIssuerEntityId = $request->getIssuer();
     // First, if there is scoping, we reject responses from idps not in the list
     if (count($scopedIdps) > 0) {
         foreach ($cachedResponses as $key => $cachedResponse) {
             if (!in_array($cachedResponse['idp'], $scopedIdps)) {
                 unset($cachedResponses[$key]);
             }
         }
     }
     if (empty($cachedResponses)) {
         return false;
     }
     $cachedResponse = $this->_pickCachedResponse($cachedResponses);
     if (!$cachedResponse) {
         return false;
     }
     $this->_server->getSessionLog()->info("Cached response found from Idp");
     // Note that we would like to repurpose the response,
     // but that's tricky as it is probably no longer valid (lifetime is usually something like 5 minutes)
     // so instead we scope the request to that Idp and trust the Idp to do the remembering.
     $this->_server->sendAuthenticationRequest($request, $cachedResponse['idp']);
     return true;
 }