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; } }