function handleResponse() { try { $binding = SAML2_Binding::getCurrentBinding(); $response = $binding->receive(); } catch (Exception $e) { return; } SimpleSAML_Logger::debug('attributequery - received message.'); if (!$response instanceof SAML2_Response) { throw new SimpleSAML_Error_Exception('Unexpected message received to attribute query example.'); } $idpEntityId = $response->getIssuer(); if ($idpEntityId === NULL) { throw new SimpleSAML_Error_Exception('Missing issuer in response.'); } $idpMetadata = $GLOBALS['metadata']->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $spMetadata = $GLOBALS['metadata']->getMetaDataConfig($GLOBALS['spEntityId'], 'saml20-sp-hosted'); $assertion = sspmod_saml_Message::processResponse($spMetadata, $idpMetadata, $response); if (count($assertion) > 1) { throw new SimpleSAML_Error_Exception('More than one assertion in received response.'); } $assertion = $assertion[0]; $dataId = $response->getRelayState(); if ($dataId === NULL) { throw new SimpleSAML_Error_Exception('RelayState was lost during request.'); } $data = $GLOBALS['session']->getData('attributequeryexample:data', $dataId); $data['attributes'] = $assertion->getAttributes(); $GLOBALS['session']->setData('attributequeryexample:data', $dataId, $data, 3600); SimpleSAML_Utilities::redirect(SimpleSAML_Utilities::selfURLNoQuery(), array('dataId' => $dataId)); }
public function getBinding() { /* Receiving the attribute query */ $binding = SAML2_Binding::getCurrentBinding(); /* Supported binding is SOAP */ if (!$binding instanceof SAML2_SOAP) { throw new SimpleSAML_Error_BadRequest('[aa] Unsupported binding. It must be SAML2_SOAP.'); } SimpleSAML_Logger::debug('[aa] binding: ' . var_export($binding, true)); return $binding; }
* Logout endpoint handler for SAML SP authentication client. * * This endpoint handles both logout requests and logout responses. */ if (!array_key_exists('PATH_INFO', $_SERVER)) { throw new SimpleSAML_Error_BadRequest('Missing authentication source id in logout URL'); } $sourceId = substr($_SERVER['PATH_INFO'], 1); $source = SimpleSAML_Auth_Source::getById($sourceId); if ($source === NULL) { throw new Exception('Could not find authentication source with id ' . $sourceId); } if (!$source instanceof sspmod_saml_Auth_Source_SP) { throw new SimpleSAML_Error_Exception('Source type changed?'); } $binding = SAML2_Binding::getCurrentBinding(); $message = $binding->receive(); $idpEntityId = $message->getIssuer(); if ($idpEntityId === NULL) { /* Without an issuer we have no way to respond to the message. */ throw new SimpleSAML_Error_BadRequest('Received message on logout endpoint without issuer.'); } $spEntityId = $source->getEntityId(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $source->getIdPMetadata($idpEntityId); $spMetadata = $source->getMetadata(); sspmod_saml_Message::validateMessage($idpMetadata, $spMetadata, $message); $destination = $message->getDestination(); //if ($destination !== NULL && $destination !== SimpleSAML_Utilities::selfURLNoQuery()) { // throw new SimpleSAML_Error_Exception('Destination in logout message is wrong.'); //}
/** * Receive a logout message. * * @param SimpleSAML_IdP $idp The IdP we are receiving it for. */ public static function receiveLogoutMessage(SimpleSAML_IdP $idp) { $binding = SAML2_Binding::getCurrentBinding(); $message = $binding->receive(); $spEntityId = $message->getIssuer(); if ($spEntityId === NULL) { /* Without an issuer we have no way to respond to the message. */ throw new SimpleSAML_Error_BadRequest('Received message on logout endpoint without issuer.'); } $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $idp->getConfig(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote'); sspmod_saml_Message::validateMessage($spMetadata, $idpMetadata, $message); if ($message instanceof SAML2_LogoutResponse) { SimpleSAML_Logger::info('Received SAML 2.0 LogoutResponse from: ' . var_export($spEntityId, TRUE)); $statsData = array('spEntityID' => $spEntityId, 'idpEntityID' => $idpMetadata->getString('entityid')); if (!$message->isSuccess()) { $statsData['error'] = $message->getStatus(); } SimpleSAML_Stats::log('saml:idp:LogoutResponse:recv', $statsData); $relayState = $message->getRelayState(); if (!$message->isSuccess()) { $logoutError = sspmod_saml_Message::getResponseError($message); SimpleSAML_Logger::warning('Unsuccessful logout. Status was: ' . $logoutError); } else { $logoutError = NULL; } $assocId = 'saml:' . $spEntityId; $idp->handleLogoutResponse($assocId, $relayState, $logoutError); } elseif ($message instanceof SAML2_LogoutRequest) { SimpleSAML_Logger::info('Received SAML 2.0 LogoutRequest from: ' . var_export($spEntityId, TRUE)); SimpleSAML_Stats::log('saml:idp:LogoutRequest:recv', array('spEntityID' => $spEntityId, 'idpEntityID' => $idpMetadata->getString('entityid'))); $spStatsId = $spMetadata->getString('core:statistics-id', $spEntityId); SimpleSAML_Logger::stats('saml20-idp-SLO spinit ' . $spStatsId . ' ' . $idpMetadata->getString('entityid')); $state = array('Responder' => array('sspmod_saml_IdP_SAML2', 'sendLogoutResponse'), 'saml:SPEntityId' => $spEntityId, 'saml:RelayState' => $message->getRelayState(), 'saml:RequestId' => $message->getId()); $assocId = 'saml:' . $spEntityId; $idp->handleLogoutRequest($state, $assocId); } else { throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message)); } }
} if (array_key_exists('IDPList', $spmetadata)) { $IDPList = array_unique(array_merge($IDPList, $spmetadata['IDPList'])); } if (isset($_GET['IDPList']) && !empty($_GET['IDPList'])) { $providers = $_GET['IDPList']; if (!is_array($providers)) { $providers = array($providers); } $IDPList = array_merge($IDPList, $providers); } $ar->setIDPList($IDPList); /* Save request information. */ $info = array(); $info['RelayState'] = $returnTo; if (array_key_exists('OnError', $_REQUEST)) { $info['OnError'] = SimpleSAML_Utilities::checkURLAllowed($_REQUEST['OnError']); } $session->setData('SAML2:SP:SSO:Info', $ar->getId(), $info); /* Select appropriate SSO endpoint */ if ($ar->getProtocolBinding() === SAML2_Const::BINDING_HOK_SSO) { $dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(SAML2_Const::BINDING_HOK_SSO)); } else { $dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(SAML2_Const::BINDING_HTTP_REDIRECT, SAML2_Const::BINDING_HTTP_POST)); } $ar->setDestination($dst['Location']); $b = SAML2_Binding::getBinding($dst['Binding']); $b->send($ar); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('CREATEREQUEST', $exception); }
/** * Start a SAML 2 logout operation. * * @param array $state The logout state. */ public function startSLO2(&$state) { assert('is_array($state)'); assert('array_key_exists("saml:logout:IdP", $state)'); assert('array_key_exists("saml:logout:NameID", $state)'); assert('array_key_exists("saml:logout:SessionIndex", $state)'); $id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent'); $idp = $state['saml:logout:IdP']; $nameId = $state['saml:logout:NameID']; $sessionIndex = $state['saml:logout:SessionIndex']; $idpMetadata = $this->getIdPMetadata($idp); $endpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT, SAML2_Const::BINDING_HTTP_POST), FALSE); if ($endpoint === FALSE) { SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.'); return; } $lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($sessionIndex); $lr->setRelayState($id); $lr->setDestination($endpoint['Location']); $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', NULL); if ($encryptNameId === NULL) { $encryptNameId = $this->metadata->getBoolean('nameid.encryption', FALSE); } if ($encryptNameId) { $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata)); } $b = SAML2_Binding::getBinding($endpoint['Binding']); $b->send($lr); assert('FALSE'); }
} try { $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpEntityId = $session->getAuthData('saml2', 'saml:sp:IdP'); if ($idpEntityId === NULL) { SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: User not authenticated with an IdP.'); SimpleSAML_Utilities::redirectTrustedURL($returnTo); } $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $SLOendpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT, SAML2_Const::BINDING_HTTP_POST), NULL); if ($SLOendpoint === NULL) { $session->doLogout('saml2'); SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: No SingleLogoutService endpoint supported in the IdP.'); SimpleSAML_Utilities::redirectTrustedURL($returnTo); } $spEntityId = isset($_GET['spentityid']) ? $_GET['spentityid'] : $metadata->getMetaDataCurrentEntityID(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-hosted'); $nameId = $session->getAuthData('saml2', 'saml:sp:NameID'); $lr = sspmod_saml_Message::buildLogoutRequest($spMetadata, $idpMetadata); $lr->setNameId($nameId); $lr->setSessionIndex($session->getAuthData('saml2', 'saml:sp:SessionIndex')); $lr->setDestination($SLOendpoint['Location']); $session->doLogout('saml2'); /* Save the $returnTo URL until the user returns from the IdP. */ $session->setData('spLogoutReturnTo', $lr->getId(), $returnTo); SimpleSAML_Logger::info('SAML2.0 - SP.initSLO: SP (' . $spEntityId . ') is sending logout request to IdP (' . $idpEntityId . ')'); $b = SAML2_Binding::getBinding($SLOendpoint['Binding']); $b->send($lr); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('CREATEREQUEST', $exception); }
/** * Function to actually send the authentication request. * * This function does not return. * * @param array &$state The state array. * @param SAML2_Binding $binding The binding. * @param SAML2_AuthnRequest $ar The authentication request. */ public function sendSAML2AuthnRequest(array &$state, SAML2_Binding $binding, SAML2_AuthnRequest $ar) { $binding->send($ar); assert('FALSE'); }
public function send(EngineBlock_Saml2_MessageAnnotationDecorator $message, AbstractRole $remoteEntity) { $bindingUrn = $message->getDeliverByBinding(); $sspMessage = $message->getSspMessage(); if ($bindingUrn === 'INTERNAL') { $this->sendInternal($message); return; } if ($this->shouldMessageBeSigned($sspMessage, $remoteEntity)) { $keyPair = $this->_server->getSigningCertificates(); $sspMessage->setCertificates(array($keyPair->getCertificate()->toPem())); $sspMessage->setSignatureKey($keyPair->getPrivateKey()->toXmlSecurityKey()); } $sspBinding = SAML2_Binding::getBinding($bindingUrn); if ($sspBinding instanceof SAML2_HTTPPost) { // SAML2int dictates that we MUST sign assertions. // The SAML2 library will do that for us, if we just set the key to sign with. if ($sspMessage instanceof SAML2_Response) { foreach ($sspMessage->getAssertions() as $assertion) { $assertion->setCertificates($sspMessage->getCertificates()); $assertion->setSignatureKey($sspMessage->getSignatureKey()); } // BWC dictates that we don't sign responses. $messageElement = $sspMessage->toUnsignedXML(); } else { $messageElement = $sspMessage->toSignedXML(); } $xml = $messageElement->ownerDocument->saveXML($messageElement); $this->validateXml($xml); $extra = ''; $extra .= method_exists($message, 'getReturn') ? '<input type="hidden" name="return" value="' . htmlspecialchars($message->getReturn()) . '">' : ''; $extra .= $sspMessage->getRelayState() ? '<input type="hidden" name="RelayState" value="' . htmlspecialchars($sspMessage->getRelayState()) . '">' : ''; $encodedMessage = htmlspecialchars(base64_encode($xml)); $action = $sspMessage->getDestination(); $log = $this->_server->getSessionLog(); $log->info('HTTP-Post: Sending Message', array('saml_message' => $xml)); $output = $this->_server->renderTemplate('form', array('action' => $action, 'message' => $encodedMessage, 'xtra' => $extra, 'name' => $message->getMessageType(), 'trace' => $this->getTraceHtml($xml))); $this->_server->sendOutput($output); } else { if ($sspBinding instanceof SAML2_HTTPRedirect) { if ($sspMessage instanceof SAML2_Response) { throw new EngineBlock_Corto_Module_Bindings_UnsupportedBindingException('May not send a Reponse via HTTP Redirect'); } $url = $sspBinding->getRedirectURL($sspMessage); $this->_server->redirect($url, $message); } else { throw new EngineBlock_Corto_Module_Bindings_Exception('Unsupported Binding'); } } }