public function createNewResponse($request, $attributes = array())
 {
     $response = $this->_createBaseResponse($request);
     $soon = $this->timeStamp($this->getCurrentMD('NotOnOrAfter', null, null, 300));
     $sessionEnd = $this->timeStamp($this->getCurrentMD('SessionEnd', null, null, 60 * 60 * 12));
     $response['saml:Assertion'] = array('_xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', '_xmlns:xs' => 'http://www.w3.org/2001/XMLSchema', '_xmlns:samlp' => 'urn:oasis:names:tc:SAML:2.0:protocol', '_xmlns:saml' => 'urn:oasis:names:tc:SAML:2.0:assertion', '_ID' => $this->getNewId(), '_Version' => '2.0', '_IssueInstant' => $response['_IssueInstant'], 'saml:Issuer' => array('__v' => $response['saml:Issuer']['__v']), 'saml:Subject' => array('saml:NameID' => array('_SPNameQualifier' => $this->getCurrentMD('entityID'), '_Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', '__v' => $this->getNewId()), 'saml:SubjectConfirmation' => array('_Method' => 'urn:oasis:names:tc:SAML:2.0:cm:bearer', 'saml:SubjectConfirmationData' => array('_NotOnOrAfter' => $soon, '_Recipient' => $response['_Destination'], '_InResponseTo' => $request['_ID']))), 'saml:Conditions' => array('_NotBefore' => $response['_IssueInstant'], '_NotOnOrAfter' => $soon, 'saml:AudienceRestriction' => array('saml:Audience' => array('__v' => $request['saml:Issuer']['__v']))), 'saml:AuthnStatement' => array('_AuthnInstant' => $response['_IssueInstant'], '_SessionNotOnOrAfter' => $sessionEnd, 'saml:SubjectLocality' => array('_Address' => $_SERVER['REMOTE_ADDR'], '_DNSName' => $_SERVER['REMOTE_HOST']), 'saml:AuthnContext' => array('saml:AuthnContextClassRef' => array('__v' => 'urn:oasis:names:tc:SAML:2.0:ac:classes:Password'))));
     if (!isset($attributes['binding'])) {
         $attributes['binding'] = array();
     }
     $attributes['binding'][] = $response['__']['ProtocolBinding'];
     foreach ((array) $attributes as $key => $vs) {
         foreach ($vs as $v) {
             $attributeStatement[$key][] = $v;
         }
     }
     $attributeConsumingServiceIndex = $request['_AttributeConsumingServiceIndex'];
     if ($attributeConsumingServiceIndex) {
         $attributeStatement['AttributeConsumingServiceIndex'] = "AttributeConsumingServiceIndex: {$attributeConsumingServiceIndex}";
     } else {
         $attributeStatement['AttributeConsumingServiceIndex'] = '-no AttributeConsumingServiceIndex given-';
     }
     $response['saml:Assertion']['saml:AttributeStatement'][0]['saml:Attribute'] = Corto_XmlToArray::array2attributes($attributeStatement);
     return $response;
 }
 /**
  *
  * @return void
  */
 public function processedAssertionConsumerService()
 {
     $response = $this->_server->getBindingsModule()->receiveResponse();
     $receivedRequest = $this->_server->getReceivedRequestFromResponse($response[Corto_XmlToArray::ATTRIBUTE_PFX . 'InResponseTo']);
     $remainingProcessingEntities =& $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['RemainingEntities'];
     if (!empty($remainingProcessingEntities)) {
         // Moar processing!
         $nextProcessingEntity = array_shift($remainingProcessingEntities);
         $this->_server->setProcessingMode();
         $newResponse = $this->_server->createEnhancedResponse($receivedRequest, $response);
         // Change the destiny of the received response
         $newResponse[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID'] = $response[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID'];
         $newResponse[Corto_XmlToArray::ATTRIBUTE_PFX . 'Destination'] = $nextProcessingEntity['Location'];
         $newResponse[Corto_XmlToArray::PRIVATE_PFX]['ProtocolBinding'] = $nextProcessingEntity['Binding'];
         $newResponse[Corto_XmlToArray::PRIVATE_PFX]['Return'] = $this->_server->getCurrentEntityUrl('processedAssertionConsumerService');
         $newResponse[Corto_XmlToArray::PRIVATE_PFX]['paramname'] = 'SAMLResponse';
         $this->_server->getBindingsModule()->send($newResponse, $nextProcessingEntity);
         return;
     } else {
         // Done processing! Send off to SP
         $response[Corto_XmlToArray::ATTRIBUTE_PFX . 'Destination'] = $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['OriginalDestination'];
         $response[Corto_XmlToArray::PRIVATE_PFX]['ProtocolBinding'] = $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['OriginalBinding'];
         $response[Corto_XmlToArray::PRIVATE_PFX]['OriginalIssuer'] = $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['OriginalIssuer'];
         $responseAssertionAttributes =& $response['saml:Assertion']['saml:AttributeStatement'][0]['saml:Attribute'];
         $attributes = Corto_XmlToArray::attributes2array($responseAssertionAttributes);
         unset($attributes['ServiceProvider']);
         $responseAssertionAttributes = Corto_XmlToArray::array2attributes($attributes);
         $this->_server->unsetProcessingMode();
         // Cache the response
         if ($this->_server->getCurrentEntitySetting('keepsession', false)) {
             $this->_cacheResponse($receivedRequest, $response, self::RESPONSE_CACHE_TYPE_OUT);
         }
         $sentResponse = $this->_server->createEnhancedResponse($receivedRequest, $response);
         $this->_server->sendResponseToRequestIssuer($receivedRequest, $sentResponse);
         return;
     }
 }