Пример #1
0
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_saml2_Message::processResponse($spMetadata, $idpMetadata, $response);
    $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));
}
Пример #2
0
 protected function createLogoutResponse($testrun, $logoutRequest, $logoutRelayState)
 {
     $this->log($testrun, 'Creating response with relaystate [' . $logoutRelayState . ']');
     $idpMetadata = SimpleSAML_Configuration::loadFromArray($this->idpmetadata);
     $spMetadata = SimpleSAML_Configuration::loadFromArray($this->metadata);
     // Get SingleLogoutService URL
     $consumerURLf = $spMetadata->getDefaultEndpoint('SingleLogoutService', array('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'));
     $consumerURL = $consumerURLf['Location'];
     /* Create an send response. */
     $response = sspmod_saml2_Message::buildLogoutResponse($idpMetadata, $spMetadata);
     $response->setRelayState($logoutRequest->getRelayState());
     $response->setInResponseTo($logoutRequest->getId());
     $keyArray = SimpleSAML_Utilities::loadPrivateKey($idpMetadata, TRUE);
     $certArray = SimpleSAML_Utilities::loadPublicKey($idpMetadata, FALSE);
     $privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
     $privateKey->loadKey($keyArray['PEM'], FALSE);
     $response->setSignatureKey($privateKey);
     if ($certArray === NULL) {
         throw new Exception('No certificates found. [1]');
     }
     if (!array_key_exists('PEM', $certArray)) {
         throw new Exception('No certificates found. [2]');
     }
     $response->setCertificates(array($certArray['PEM']));
     #$this->tweakResponse($testrun, $response);
     $msgStr = $response->toUnsignedXML();
     #$this->tweakResponseDOM($testrun, $msgStr);
     $msgStr = $msgStr->ownerDocument->saveXML($msgStr);
     #	echo '<pre>'; echo(htmlspecialchars($msgStr)); exit;
     #		$msgStr = base64_encode($msgStr);
     #		$msgStr = htmlspecialchars($msgStr);
     return array('url' => $consumerURL, 'Response' => $msgStr, 'ResponseObj' => $response, 'RelayState' => $logoutRelayState);
 }
Пример #3
0
/**
 * Helper function for handling exception/errors.
 *
 * This function will send an error response to the SP which contacted this IdP.
 *
 * @param Exception $exception  The exception.
 */
function handleError(Exception $exception)
{
    global $requestcache, $config, $metadata, $idpentityid;
    assert('is_array($requestcache)');
    assert('array_key_exists("Issuer", $requestcache)');
    $issuer = $requestcache['Issuer'];
    if (array_key_exists('RequestID', $requestcache)) {
        $requestID = $requestcache['RequestID'];
    } else {
        $requestID = NULL;
    }
    if (array_key_exists('RelayState', $requestcache)) {
        $relayState = $requestcache['RelayState'];
    } else {
        $relayState = NULL;
    }
    $error = sspmod_saml2_Error::fromException($exception);
    SimpleSAML_Logger::warning('Returning error to sp: ' . var_export($issuer, TRUE));
    $error->logWarning();
    try {
        $idpMetadata = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
        $spMetadata = $metadata->getMetaDataConfig($issuer, 'saml20-sp-remote');
        if (array_key_exists('ConsumerURL', $requestcache)) {
            $consumerURL = $requestcache['ConsumerURL'];
        } else {
            $urlArray = $spMetadata->getArrayizeString('AssertionConsumerService');
            $consumerURL = $urlArray[0];
        }
        $ar = sspmod_saml2_Message::buildResponse($idpMetadata, $spMetadata, $consumerURL);
        $ar->setInResponseTo($requestID);
        $ar->setRelayState($relayState);
        $ar->setStatus(array('Code' => $error->getStatus(), 'SubCode' => $error->getSubStatus(), 'Message' => $error->getStatusMessage()));
        $binding = new SAML2_HTTPPost();
        $binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
        $binding->send($ar);
    } catch (Exception $e) {
        SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $e);
    }
}
Пример #4
0
$spEntityId = $source->getEntityId();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-remote');
$spMetadata = $source->getMetadata();
sspmod_saml2_Message::validateMessage($idpMetadata, $spMetadata, $message);
if ($message instanceof SAML2_LogoutResponse) {
    $relayState = $message->getRelayState();
    if ($relayState === NULL) {
        /* Somehow, our RelayState has been lost. */
        throw new SimpleSAML_Error_BadRequest('Missing RelayState in logout response.');
    }
    if (!$message->isSuccess()) {
        SimpleSAML_Logger::warning('Unsuccessful logout. Status was: ' . sspmod_saml2_Message::getResponseError($message));
    }
    $state = SimpleSAML_Auth_State::loadState($relayState, sspmod_saml2_Auth_Source_SP::STAGE_LOGOUTSENT);
    SimpleSAML_Auth_Source::completeLogout($state);
} elseif ($message instanceof SAML2_LogoutRequest) {
    SimpleSAML_Logger::debug('module/saml2/sp/logout: Request from ' . $idpEntityId);
    SimpleSAML_Logger::stats('saml20-idp-SLO idpinit ' . $spEntityId . ' ' . $idpEntityId);
    /* Notify source of logout, so that it may call logout callbacks. */
    $source->onLogout($idpEntityId);
    /* Create an send response. */
    $lr = sspmod_saml2_Message::buildLogoutResponse($spMetadata, $idpMetadata);
    $lr->setRelayState($message->getRelayState());
    $lr->setInResponseTo($message->getId());
    $binding = new SAML2_HTTPRedirect();
    $binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
    $binding->send($lr);
} else {
    throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message));
}
Пример #5
0
if ($source === NULL) {
    throw new Exception('Could not find authentication source with id ' . $sourceId);
}
$idp = $response->getIssuer();
if ($idp === NULL) {
    throw new Exception('Missing <saml:Issuer> in message delivered to AssertionConsumerService.');
}
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$idpMetadata = $metadata->getMetaDataConfig($idp, 'saml20-idp-remote');
$spMetadata = $source->getMetadata();
/* Check if the IdP is allowed to authenticate users for this authentication source. */
if (!$source->isIdPValid($idp)) {
    throw new Exception('Invalid IdP responded for authentication source with id ' . $sourceId . '. The IdP was ' . var_export($idp, TRUE));
}
try {
    $assertion = sspmod_saml2_Message::processResponse($spMetadata, $idpMetadata, $response);
} catch (sspmod_saml2_Error $e) {
    /* The status of the response wasn't "success". */
    $e = $e->toException();
    SimpleSAML_Auth_State::throwException($state, $e);
}
$nameId = $assertion->getNameId();
$sessionIndex = $assertion->getSessionIndex();
/* We need to save the NameID and SessionIndex for logout. */
$logoutState = array(sspmod_saml2_Auth_Source_SP::LOGOUT_IDP => $idp, sspmod_saml2_Auth_Source_SP::LOGOUT_NAMEID => $nameId, sspmod_saml2_Auth_Source_SP::LOGOUT_SESSIONINDEX => $sessionIndex);
$state['LogoutState'] = $logoutState;
$spMetadataArray = $spMetadata->toArray();
$idpMetadataArray = $idpMetadata->toArray();
$pc = new SimpleSAML_Auth_ProcessingChain($idpMetadataArray, $spMetadataArray, 'sp');
$authProcState = array('saml2:sp:IdP' => $idp, 'saml2:sp:State' => $state, 'ReturnCall' => array('sspmod_saml2_Auth_Source_SP', 'onProcessingCompleted'), 'Attributes' => $assertion->getAttributes(), 'Destination' => $spMetadataArray, 'Source' => $idpMetadataArray);
$pc->processState($authProcState);
Пример #6
0
        if (count($values) === 0) {
            /* Return all attributes. */
            $returnAttributes[$name] = $attributes[$name];
            continue;
        }
        /* Filter which attribute values we should return. */
        $returnAttributes[$name] = array_intersect($values, $attributes[$name]);
    }
}
/* $returnAttributes contains the attributes we should return. Send them. */
$assertion = new SAML2_Assertion();
$assertion->setDestination($endpoint);
$assertion->setIssuer($idpEntityId);
$assertion->setNameId($query->getNameId());
$assertion->setNotBefore(time());
$assertion->setNotOnOrAfter(time() + 5 * 60);
$assertion->setInResponseTo($query->getId());
$assertion->setValidAudiences(array($spEntityId));
$assertion->setAttributes($returnAttributes);
$assertion->setAttributeNameFormat($attributeNameFormat);
sspmod_saml2_Message::addSign($idpMetadata, $spMetadata, $assertion);
$response = new SAML2_Response();
$response->setRelayState($query->getRelayState());
$response->setDestination($endpoint);
$response->setIssuer($idpEntityId);
$response->setInResponseTo($query->getId());
$response->setAssertions(array($assertion));
sspmod_saml2_Message::addSign($idpMetadata, $spMetadata, $response);
$binding = new SAML2_HTTPPost();
$binding->setDestination(sspmod_saml2_Message::getDebugDestination());
$binding->send($response);
Пример #7
0
 /**
  * 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->getString('SingleLogoutService', FALSE);
     if ($endpoint === FALSE) {
         SimpleSAML_Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.');
         return;
     }
     $lr = sspmod_saml2_Message::buildLogoutRequest($this->metadata, $idpMetadata);
     $lr->setNameId($nameId);
     $lr->setSessionIndex($sessionIndex);
     $lr->setRelayState($id);
     $b = new SAML2_HTTPRedirect();
     $b->setDestination(sspmod_SAML2_Message::getDebugDestination());
     $b->send($lr);
     assert('FALSE');
 }
$logouttype = $idpMetadata->getString('logouttype', 'traditional');
if ($logouttype !== 'iframe') {
    SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS', new Exception('This IdP is configured to use logout type [' . $logouttype . '], but this endpoint is only available for IdP using logout type [iframe]'));
}
if (!isset($_REQUEST['SAMLResponse'])) {
    SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS', new Exception('No valid SAMLResponse found? Probably some error in remote partys metadata that sends something to this endpoint that is not SAML LogoutResponses'));
}
$binding = SAML2_Binding::getCurrentBinding();
$logoutResponse = $binding->receive();
if (!$logoutResponse instanceof SAML2_LogoutResponse) {
    SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS', new Exception('Message received on response endpoint wasn\'t a response. Was: ' . get_class($logoutResponse)));
}
$spEntityId = $logoutResponse->getIssuer();
if ($spEntityId === NULL) {
    SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SLOSERVICEPARAMS', new Exception('Missing issuer on logout response.'));
}
$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
sspmod_saml2_Message::validateMessage($spMetadata, $idpMetadata, $logoutResponse);
$sphash = sha1($spEntityId);
setcookie('spstate-' . $sphash, '1');
// Duration: 2 hours
SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutServiceiFrameResponse: Logging out completed');
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<title>Logout OK</title>
</head>
<body>OK</body>
</html>';
Пример #9
0
        SimpleSAML_Utilities::redirect($extDiscoveryStorage, array('entityID' => $spentityid, 'return' => SimpleSAML_Utilities::addURLparameter($discourl, array('return' => SimpleSAML_Utilities::selfURL(), 'remember' => 'true', 'entityID' => $spentityid, 'returnIDParam' => 'idpentityid')), 'returnIDParam' => 'idpentityid', 'isPassive' => 'true'));
    }
    $discoparameters = array('entityID' => $spentityid, 'return' => SimpleSAML_Utilities::selfURL(), 'returnIDParam' => 'idpentityid');
    $discoparameters['isPassive'] = $isPassive;
    if (sizeof($reachableIDPs) > 0) {
        $discoparameters['IDPList'] = $reachableIDPs;
    }
    SimpleSAML_Utilities::redirect($discourl, $discoparameters);
}
/*
 * Create and send authentication request to the IdP.
 */
try {
    $spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-hosted');
    $idpMetadata = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-remote');
    $ar = sspmod_saml2_Message::buildAuthnRequest($spMetadata, $idpMetadata);
    $assertionConsumerServiceURL = $metadata->getGenerated('AssertionConsumerService', 'saml20-sp-hosted');
    $ar->setAssertionConsumerServiceURL($assertionConsumerServiceURL);
    $ar->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST);
    $ar->setRelayState($_REQUEST['RelayState']);
    if ($isPassive) {
        $ar->setIsPassive(TRUE);
    }
    if ($forceAuthn) {
        $ar->setForceAuthn(TRUE);
    }
    if (array_key_exists('IDPList', $spmetadata)) {
        $IDPList = array_unique(array_merge($IDPList, $spmetadata['IDPList']));
    }
    if (isset($_GET['IDPList']) && !empty($_GET['IDPList'])) {
        $providers = $_GET['IDPList'];
Пример #10
0
 /**
  * Handle logout operation.
  *
  * @param array $state  The logout state.
  */
 public function logout(&$state)
 {
     assert('is_array($state)');
     assert('array_key_exists(self::LOGOUT_IDP, $state)');
     assert('array_key_exists(self::LOGOUT_NAMEID, $state)');
     assert('array_key_exists(self::LOGOUT_SESSIONINDEX, $state)');
     $id = SimpleSAML_Auth_State::saveState($state, self::STAGE_LOGOUTSENT);
     $idp = $state[self::LOGOUT_IDP];
     $nameId = $state[self::LOGOUT_NAMEID];
     $sessionIndex = $state[self::LOGOUT_SESSIONINDEX];
     if (array_key_exists('value', $nameId)) {
         /*
          * This session was saved by an old version of simpleSAMLphp.
          * Convert to the new NameId format.
          *
          * TODO: Remove this conversion once every session should use the new format.
          */
         $nameId['Value'] = $nameId['value'];
         unset($nameId['value']);
     }
     $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
     $idpMetadata = $metadata->getMetaDataConfig($idp, 'saml20-idp-remote');
     $lr = sspmod_saml2_Message::buildLogoutRequest($this->metadata, $idpMetadata);
     $lr->setNameId($nameId);
     $lr->setSessionIndex($sessionIndex);
     $lr->setRelayState($id);
     $b = new SAML2_HTTPRedirect();
     $b->setDestination(sspmod_SAML2_Message::getDebugDestination());
     $b->send($lr);
     assert('FALSE');
 }
/*
 * Generate a list of all service providers, and create a LogoutRequest message for all these SPs.
 */
$listofsps = $session->get_sp_list();
$sparray = array();
$sparrayNoLogout = array();
foreach ($listofsps as $spentityid) {
    // ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
    $nameId = $session->getSessionNameId('saml20-sp-remote', $spentityid);
    if ($nameId === NULL) {
        $nameId = $session->getNameID();
    }
    $spMetadata = $metadata->getMetaDataConfig($spentityid, 'saml20-sp-remote');
    $name = $spMetadata->getValue('name', $spentityid);
    try {
        $lr = sspmod_saml2_Message::buildLogoutRequest($idpMetadata, $spMetadata);
        $lr->setSessionIndex($session->getSessionIndex());
        $lr->setNameId($nameId);
        $httpredirect = new SAML2_HTTPRedirect();
        $url = $httpredirect->getRedirectURL($lr);
        $sparray[$spentityid] = array('url' => $url, 'name' => $name);
    } catch (Exception $e) {
        $sparrayNoLogout[$spentityid] = array('name' => $name);
    }
}
SimpleSAML_Logger::debug('SAML2.0 - SP Counter. other SPs with SLO support (' . count($sparray) . ')  without SLO support (' . count($sparrayNoLogout) . ')');
#print_r($sparray);
/*
 * If the user is not logged into any other SPs.
 */
if (count($sparray) + count($sparrayNoLogout) === 0) {