Revision: 2068
Author: olavmrk
Date: Tue Jan 5 02:19:08 2010
Log: saml2/idp: Move to new IdP core.
http://code.google.com/p/simplesamlphp/source/detail?r=2068
Added:
/trunk/modules/saml/lib/IdP
/trunk/modules/saml/lib/IdP/SAML2.php
Modified:
/trunk/www/saml2/idp/SSOService.php
=======================================
--- /dev/null
+++ /trunk/modules/saml/lib/IdP/SAML2.php Tue Jan 5 02:19:08 2010
@@ -0,0 +1,275 @@
+<?php
+
+/**
+ * IdP implementation for SAML 2.0 protocol.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_saml_IdP_SAML2 {
+
+ /**
+ * Send a response to the SP.
+ *
+ * @param array $state The authentication state.
+ */
+ public static function sendResponse(array $state) {
+ assert('isset($state["Attributes"])');
+ assert('isset($state["SPMetadata"])');
+ assert('isset($state["saml:ConsumerURL"])');
+ assert('array_key_exists("saml:RequestId", $state)'); // Can be
NULL.
+ assert('array_key_exists("saml:RelayState", $state)'); // Can
be NULL.
+
+ $spMetadata = $state["SPMetadata"];
+ $spEntityId = $spMetadata['entityid'];
+ $spMetadata =
SimpleSAML_Configuration::loadFromArray($spMetadata,
+ '$metadata[' . var_export($spEntityId, TRUE) . ']');
+
+ SimpleSAML_Logger::info('Sending SAML 2.0 Response to ' .
var_export($spEntityId, TRUE));
+
+ $attributes = $state['Attributes'];
+ $requestId = $state['saml:RequestId'];
+ $relayState = $state['saml:RelayState'];
+ $consumerURL = $state['saml:ConsumerURL'];
+
+ $idp = SimpleSAML_IdP::getByState($state);
+
+ $idpMetadata = $idp->getConfig();
+
+ $assertion = sspmod_saml2_Message::buildAssertion($idpMetadata,
$spMetadata, $attributes, $consumerURL);
+ $assertion->setInResponseTo($requestId);
+
+ /* Maybe encrypt the assertion. */
+ $assertion =
sspmod_saml2_Message::encryptAssertion($idpMetadata,
$spMetadata, $assertion);
+
+ /* Create the response. */
+ $ar = sspmod_saml2_Message::buildResponse($idpMetadata,
$spMetadata,
$consumerURL);
+ $ar->setInResponseTo($requestId);
+ $ar->setRelayState($relayState);
+ $ar->setAssertions(array($assertion));
+
+ /* Add the session association (for logout). */
+ $session = SimpleSAML_Session::getInstance();
+ $session->add_sp_session($spEntityId);
+ $session->setSessionNameId('saml20-sp-remote', $spEntityId,
$assertion->getNameId());
+
+ /* Send the response. */
+ $binding = new SAML2_HTTPPost();
+
$binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
+ $binding->send($ar);
+ }
+
+
+ /**
+ * Handle authentication error.
+ *
+ * SimpleSAML_Error_Exception $exception The exception.
+ * @param array $state The error state.
+ */
+ public static function handleAuthError(SimpleSAML_Error_Exception
$exception, array $state) {
+ assert('isset($state["SPMetadata"])');
+ assert('isset($state["saml:ConsumerURL"])');
+ assert('array_key_exists("saml:RequestId", $state)'); // Can be
NULL.
+ assert('array_key_exists("saml:RelayState", $state)'); // Can
be NULL.
+
+ $spMetadata = $state["SPMetadata"];
+ $spEntityId = $spMetadata['entityid'];
+ $spMetadata =
SimpleSAML_Configuration::loadFromArray($spMetadata,
+ '$metadata[' . var_export($spEntityId, TRUE) . ']');
+
+ $requestId = $state['saml:RequestId'];
+ $relayState = $state['saml:RelayState'];
+ $consumerURL = $state['saml:ConsumerURL'];
+
+ $idp = SimpleSAML_IdP::getByState($state);
+
+ $idpMetadata = $idp->getConfig();
+
+ $error = sspmod_saml2_Error::fromException($exception);
+
+ SimpleSAML_Logger::warning('Returning error to sp: ' .
var_export($spEntityId, TRUE));
+ $error->logWarning();
+
+ $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);
+ }
+
+
+ /**
+ * Receive an authentication request.
+ *
+ * @param SimpleSAML_IdP $idp The IdP we are receiving it for.
+ */
+ public static function receiveAuthnRequest(SimpleSAML_IdP $idp) {
+
+ $metadata =
SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+ $idpMetadata = $idp->getConfig();
+
+ if (isset($_REQUEST['spentityid'])) {
+ /* IdP initiated authentication. */
+
+ if (isset($_REQUEST['cookieTime'])) {
+ $cookieTime = (int)$_REQUEST['cookieTime'];
+ if ($cookieTime + 5 > time()) {
+ /*
+ * Less than five seconds has passed
since we were
+ * here the last time. Cookies are
probably disabled.
+ */
+
SimpleSAML_Utilities::checkCookie(SimpleSAML_Utilities::selfURL());
+ }
+ }
+
+ $spEntityId = (string)$_REQUEST['spentityid'];
+ $spMetadata =
$metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
+
+ if (isset($_REQUEST['RelayState'])) {
+ $relayState = (string)$_REQUEST['RelayState'];
+ } else {
+ $relayState = NULL;
+ }
+
+ $requestId = NULL;
+ $IDPList = array();
+ $forceAuthn = FALSE;
+ $isPassive = FALSE;
+ $consumerURL = NULL;
+
+ SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: IdP
initiated
authentication: '. var_export($spEntityId, TRUE));
+
+ } elseif (isset($_REQUEST['RequestID'])) {
+ /*
+ * To allow for upgrading while people are logging in.
+ * Should be removed in 1.7.
+ */
+
+ SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService:
RequestID
received.');
+
+ $session = SimpleSAML_Session::getInstance();
+
+ $requestCache = $session->getAuthnRequest('saml2',
(string)$_REQUEST['RequestID']);
+ if (!$requestCache) {
+ throw new Exception('Could not retrieve cached
request...');
+ }
+
+ $spEntityId = $requestCache['Issuer'];
+ $spMetadata =
$metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
+
+ $relayState = $requestCache['RelayState'];
+ $requestId = $requestCache['RequestID'];
+ $forceAuthn = $requestCache['ForceAuthn'];
+ $isPassive = $requestCache['IsPassive'];
+
+ if (isset($requestCache['IDPList'])) {
+ $IDPList = $requestCache['IDPList'];
+ } else {
+ $IDPList = array();
+ }
+
+ if (isset($requestCache['ConsumerURL'])) {
+ $consumerURL = $requestCache['ConsumerURL'];
+ } else {
+ $consumerURL = NULL;
+ }
+
+ } else {
+
+ $binding = SAML2_Binding::getCurrentBinding();
+ $request = $binding->receive();
+
+ if (!($request instanceof SAML2_AuthnRequest)) {
+ throw new SimpleSAML_Error_BadRequest('Message
received on
authentication request endpoint wasn\'t an authentication request.');
+ }
+
+ $spEntityId = $request->getIssuer();
+ if ($spEntityId === NULL) {
+ throw new SimpleSAML_Error_BadRequest('Received
message on
authentication request endpoint without issuer.');
+ }
+ $spMetadata =
$metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
+
+ sspmod_saml2_Message::validateMessage($spMetadata,
$idpMetadata,
$request);
+
+ $relayState = $request->getRelayState();
+
+ $requestId = $request->getId();
+ $IDPList = $request->getIDPList();
+ $forceAuthn = $request->getForceAuthn();
+ $isPassive = $request->getIsPassive();
+ $consumerURL =
$request->getAssertionConsumerServiceURL();
+
+ SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService:
Incomming
Authentication request: '. var_export($spEntityId, TRUE));
+ }
+
+
+ if ($consumerURL !== NULL) {
+ $found = FALSE;
+ foreach
($spMetadata->getEndpoints('AssertionConsumerService') as $ep) {
+ if ($ep['Binding'] !==
SAML2_Const::BINDING_HTTP_POST) {
+ continue;
+ }
+ if ($ep['Location'] !== $consumerURL) {
+ continue;
+ }
+ $found = TRUE;
+ break;
+ }
+
+ if (!$found) {
+ SimpleSAML_Logger::warning('Authentication
request from ' .
var_export($spEntityId, TRUE) .
+ ' contains invalid
AssertionConsumerService URL. Was ' .
+ var_export($consumerURL, TRUE) . '.');
+ $consumerURL = NULL;
+ }
+ }
+ if ($consumerURL === NULL) {
+ /* Not specified or invalid. Use default. */
+ $consumerURL =
$spMetadata->getDefaultEndpoint('AssertionConsumerService',
array(SAML2_Const::BINDING_HTTP_POST));
+ $consumerURL = $consumerURL['Location'];
+ }
+
+ $IDPList = array_unique(array_merge($IDPList,
$spMetadata->getArrayizeString('IDPList', array())));
+
+ if (!$forceAuthn) {
+ $forceAuthn = $spMetadata->getBoolean('ForceAuthn',
FALSE);
+ }
+
+ $sessionLostParams = array(
+ 'spentityid' => $spEntityId,
+ 'cookieTime' => time(),
+ );
+ if ($relayState !== NULL) {
+ $sessionLostParams['RelayState'] = $relayState;
+ }
+
+ $sessionLostURL = SimpleSAML_Utilities::addURLparameter(
+ SimpleSAML_Utilities::selfURLNoQuery(),
+ $sessionLostParams);
+
+ $state = array(
+ 'Responder' => array('sspmod_saml_IdP_SAML2',
'sendResponse'),
+ SimpleSAML_Auth_State::EXCEPTION_HANDLER_FUNC =>
array('sspmod_saml_IdP_SAML2', 'handleAuthError'),
+ SimpleSAML_Auth_State::RESTART => $sessionLostURL,
+
+ 'SPMetadata' => $spMetadata->toArray(),
+ 'saml:RelayState' => $relayState,
+ 'saml:RequestId' => $requestId,
+ 'saml:IDPList' => $IDPList,
+ 'ForceAuthn' => $forceAuthn,
+ 'isPassive' => $isPassive,
+ 'saml:ConsumerURL' => $consumerURL,
+ );
+
+ $idp->handleAuthenticationRequest($state);
+ }
+
+}
=======================================
--- /trunk/www/saml2/idp/SSOService.php Wed Dec 2 03:52:24 2009
+++ /trunk/www/saml2/idp/SSOService.php Tue Jan 5 02:19:08 2010
@@ -11,486 +11,28 @@
require_once('../../../www/_include.php');
-$config = SimpleSAML_Configuration::getInstance();
-$metadata =
SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-$session = SimpleSAML_Session::getInstance();
+SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP
endpoint SSOService');
try {
- $idpentityid =
$metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
- $idmetaindex =
$metadata->getMetaDataCurrentEntityID('saml20-idp-hosted', 'metaindex');
- $idpmetadata = $metadata->getMetaDataCurrent('saml20-idp-hosted');
-
- if (!array_key_exists('auth', $idpmetadata)) {
- throw new Exception('Missing mandatory parameter in SAML 2.0
IdP Hosted
Metadata: [auth]');
- }
-
-} catch (Exception $exception) {
- SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA',
$exception);
-}
-
-SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP
endpoint SSOService');
-
-if (!$config->getBoolean('enable.saml20-idp', false))
- SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS');
-
-
-/**
- * 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;
+
+ $config = SimpleSAML_Configuration::getInstance();
+ if (!$config->getBoolean('enable.saml20-idp', FALSE)) {
+ throw new SimpleSAML_Error_Error('NOACCESS');
}
- 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 {
- $consumerURL =
$spMetadata->getDefaultEndpoint('AssertionConsumerService',
array(SAML2_Const::BINDING_HTTP_POST));
- $consumerURL = $consumerURL['Location'];
- }
-
- $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);
- }
+ $metadata =
SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+ $idpEntityId =
$metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+ $idp = SimpleSAML_IdP::getById('saml2:' . $idpEntityId);
+ sspmod_saml_IdP_SAML2::receiveAuthnRequest($idp);
+ assert('FALSE');
+
+} catch(SimpleSAML_Error_Error $e) {
+
+ $e->show();
+
+} catch(Exception $e) {
+
+ $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $e);
+ $e->show();
}
-
-
-/*
- * Initiate some variables
- */
-$isPassive = $forceAuthn = FALSE;
-
-$IDPList = array();
-
-/*
- * If the SAMLRequest query parameter is set, we got an incoming
Authentication Request
- * at this interface.
- *
- * In this case, what we should do is to process the request and set the
neccessary information
- * from the request into the session object to be used later.
- *
- */
-if (isset($_REQUEST['SAMLRequest'])) {
-
- try {
- $binding = SAML2_Binding::getCurrentBinding();
- $authnrequest = $binding->receive();
-
- if (!($authnrequest instanceof SAML2_AuthnRequest)) {
- throw new SimpleSAML_Error_BadRequest('Message received
on
authentication request endpoint wasn\'t an authentication request.');
- }
-
- $requestid = $authnrequest->getId();
- $issuer = $authnrequest->getIssuer();
- if ($issuer === NULL) {
- throw new SimpleSAML_Error_BadRequest('Received message
on
authentication request endpoint without issuer.');
- }
-
- $spMetadata = $metadata->getMetaDataConfig($issuer,
'saml20-sp-remote');
-
- sspmod_saml2_Message::validateMessage(
- $spMetadata,
- $metadata->getMetaDataConfig($idpentityid,
'saml20-idp-hosted'),
- $authnrequest);
-
- /*
- * Create an assoc array of the request to store in the session
cache.
- */
- $requestcache = array(
- 'RequestID' => $requestid,
- 'Issuer' => $issuer,
- 'RelayState' => $authnrequest->getRelayState()
- );
-
-
-
- $consumerURL = $authnrequest->getAssertionConsumerServiceURL();
- if ($consumerURL !== NULL) {
- $found = FALSE;
- foreach
($spMetadata->getEndpoints('AssertionConsumerService') as $ep) {
- if ($ep['Binding'] !==
SAML2_Const::BINDING_HTTP_POST) {
- continue;
- }
- if ($ep['Location'] !== $consumerURL) {
- continue;
- }
- $requestcache['ConsumerURL'] = $consumerURL;
- $found = TRUE;
- break;
- }
-
- if (!$found) {
- SimpleSAML_Logger::warning('Authentication
request from ' .
var_export($issuer, TRUE) .
- ' contains invalid
AssertionConsumerService URL. Was ' .
- var_export($consumerURL, TRUE) . '.');
- }
- }
-
- $IDPList = $authnrequest->getIDPList();
- $IDPList = array_unique(array_merge($IDPList,
$spMetadata->getArrayizeString('IDPList', array())));
- $requestcache['IDPList'] = $IDPList;
-
- /*
- * Handle the ForceAuthn option.
- */
- $forceAuthn = $spMetadata->getBoolean('ForceAuthn', FALSE);
- if($authnrequest->getForceAuthn()) {
- /* The ForceAuthn flag was set to true in the
authentication request. */
- $forceAuthn = TRUE;
- }
-
- $isPassive = $authnrequest->getIsPassive();
- /*
- * The ForceAuthn flag was set to true in the authentication
request
- * and IsPassive was not - IsPassive overrides ForceAuthn thus
the check
- *
- */
-
- if($forceAuthn && !$isPassive) {
- /* ForceAuthn is enabled. Mark the request as needing
authentication.
This flag
- * will be cleared by a call to setAuthenticated(TRUE,
...) to the
current session.
- *
- */
- $requestcache['NeedAuthentication'] = TRUE;
- }
- $requestcache['IsPassive'] = $isPassive;
- $requestcache['ForceAuthn'] = $forceAuthn;
-
- SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Incomming
Authentication request: '.$issuer.' id '.$requestid);
-
- } catch(Exception $exception) {
-
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'PROCESSAUTHNREQUEST',
$exception);
- }
-
-} elseif(isset($_REQUEST[SimpleSAML_Auth_State::EXCEPTION_PARAM])) {
- /*
- * We have received an exception. It can either be from the
authentication module,
- * or from the authentication processing filters.
- */
-
- $state = SimpleSAML_Auth_State::loadExceptionState();
- if (array_key_exists('core:saml20-idp:requestcache', $state)) {
- /* This was from a processing chain. */
- $requestcache = $state['core:saml20-idp:requestcache'];
-
- } elseif (array_key_exists('RequestID', $_REQUEST)) {
- /* This was from an authentication module. */
- $authId = $_REQUEST['RequestID'];
- $requestcache = $session->getAuthnRequest('saml2', $authId);
- if (!$requestcache) {
- throw new Exception('Could not retrieve saved request
while handling
exceptions. RequestID=' . var_export($authId, TRUE));
- }
-
- } else {
- /* We have no idea where this comes from. We have received a
bad
request. */
- throw new Exception('Bad request to exception handing code.');
- }
-
- assert('array_key_exists(SimpleSAML_Auth_State::EXCEPTION_DATA,
$state)');
- $exception = $state[SimpleSAML_Auth_State::EXCEPTION_DATA];
-
- handleError($exception);
-
-
-/*
- * If we did not get an incoming Authenticaiton Request, we need a
RequestID parameter.
- *
- * The RequestID parameter is used to retrieve the information stored in
the session object
- * related to the request that was received earlier. Usually the request
is processed with
- * code above, then the user is redirected to some login module, and when
successfully authenticated
- * the user isredirected back to this endpoint, and then the user will
need to have the RequestID
- * parmeter attached.
- */
-} elseif(isset($_GET['RequestID'])) {
-
- try {
-
- SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Got incoming
authentication ID');
-
- $authId = $_GET['RequestID'];
- $requestcache = $session->getAuthnRequest('saml2', $authId);
- if (!$requestcache) {
- throw new Exception('Could not retrieve cached
RequestID = ' . $authId);
- }
-
- } catch(Exception $exception) {
-
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'CACHEAUTHNREQUEST',
$exception);
- }
-
-} elseif(isset($_REQUEST[SimpleSAML_Auth_ProcessingChain::AUTHPARAM])) {
-
- /* Resume from authentication processing chain. */
- $authProcId = $_REQUEST[SimpleSAML_Auth_ProcessingChain::AUTHPARAM];
- $authProcState =
SimpleSAML_Auth_ProcessingChain::fetchProcessedState($authProcId);
- $requestcache = $authProcState['core:saml20-idp:requestcache'];
-
-/**
- * If the spentityid parameter is provided, we will fallback to a
unsolited response to the SP.
- */
-} elseif(array_key_exists('spentityid', $_GET)) {
-
- if (isset($_REQUEST['cookieTime'])) {
- $cookieTime = (int)$_REQUEST['cookieTime'];
- if ($cookieTime + 3 > time()) {
- /*
- * Less than three seconds has passed since we were
- * here the last time. Cookies are probably disabled.
- */
-
SimpleSAML_Utilities::checkCookie(SimpleSAML_Utilities::selfURL());
- }
- }
-
- /* Creating a request cache, even though there was no request, and
adding
the
- * information that is neccessary to be able to respond with an
unsolited
response
- */
- $requestcache = array(
- 'Issuer' => $_GET['spentityid'],
- );
-
- if (isset($_GET['RelayState'])) {
- $requestcache['RelayState'] = $_GET['RelayState'];
- }
-
-} else {
-
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'SSOSERVICEPARAMS');
-}
-
-
-/* Check whether we should authenticate with an AuthSource. Any time the
auth-option matches a
- * valid AuthSource, we assume that this is the case.
- */
-if(SimpleSAML_Auth_Source::getById($idpmetadata['auth']) !== NULL) {
- /* Authenticate with an AuthSource. */
- $authSource = TRUE;
- $authority = $idpmetadata['auth'];
-} else {
- $authSource = FALSE;
- $authority = SimpleSAML_Utilities::getAuthority($idpmetadata);
-}
-
-
-/**
- * As we have passed the code above, we have an associated request that is
already processed.
- *
- * Now we check whether we have a authenticated session. If we do not have
an authenticated session,
- * we look up in the metadata of the IdP, to see what authenticaiton
module to use, then we redirect
- * the user to the authentication module, to authenticate. Later the user
is redirected back to this
- * endpoint - then the session is authenticated and set, and the user is
redirected back with a RequestID
- * parameter so we can retrieve the cached information from the request.
- */
-
-if (!isset($session) || !$session->isValid($authority) ) {
- /* We don't have a valid session. */
- $needAuth = TRUE;
-} elseif (array_key_exists('NeedAuthentication', $requestcache) &&
$requestcache['NeedAuthentication']) {
- /* We have a valid session, but ForceAuthn is on. */
- $needAuth = TRUE;
-} elseif ((sizeof($IDPList) > 0 && $session->getidp() !== null
&& !in_array($session->getidp(), $IDPList))) {
- /* we do have a valid session but not with one of the scoped idps. */
- $needAuth = TRUE;
-} else {
- /* We have a valid session. */
- $needAuth = FALSE;
-}
-
-if($needAuth && !$isPassive) {
-
- SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Will go to
authentication module ' . $idpmetadata['auth']);
-
- $authId = SimpleSAML_Utilities::generateID();
- $session->setAuthnRequest('saml2', $authId, $requestcache);
-
- $redirectTo = SimpleSAML_Utilities::selfURLNoQuery() . '?RequestID=' .
urlencode($authId);
-
- if($authSource) {
- /* Authenticate with an AuthSource. */
-
- /* The user will be redirected to this URL if the session is
lost. This
will cause an
- * unsoliced authentication response to be sent to the SP.
- */
- $sessionLostParams = array(
- 'spentityid' => $requestcache['Issuer'],
- 'cookieTime' => time(),
- );
- if (isset($requestcache['RelayState'])) {
- $sessionLostParams['RelayState'] =
$requestcache['RelayState'];
- }
-
- $sessionLostURL = SimpleSAML_Utilities::addURLparameter(
- $metadata->getGenerated('SingleSignOnService',
'saml20-idp-hosted'),
- $sessionLostParams);
-
- $hints = array(
- 'SPMetadata' =>
$metadata->getMetaData($requestcache['Issuer'], 'saml20-sp-remote'),
- 'IdPMetadata' => $idpmetadata,
- SimpleSAML_Auth_State::RESTART => $sessionLostURL,
- );
-
- SimpleSAML_Auth_Default::initLogin($idpmetadata['auth'],
$redirectTo,
$redirectTo, $hints);
- } else {
- $authurl = '/' . $config->getBaseURL() . $idpmetadata['auth'];
-
- SimpleSAML_Utilities::redirect($authurl, array(
- 'RelayState' => $redirectTo,
- 'AuthId' => $authId,
- 'protocol' => 'saml2',
- ));
- }
-
-} elseif($needAuth) {
- /* We have a passive request, but need authentication. Send back a
response indicating that
- * the user didn't have a valid session.
- */
-
- handleError(new SimpleSAML_Error_NoPassive('Passive authentication
requested, but no session available.'));
-
-/**
- * We got an request, and we have a valid session. Then we send an
AuthnResponse back to the
- * service.
- */
-} else {
-
- try {
-
- $spentityid = $requestcache['Issuer'];
- $spMetadata =
$metadata->getMetaDataConfig($spentityid, 'saml20-sp-remote');
-
- SimpleSAML_Logger::info('SAML2.0 - IdP.SSOService: Sending back
AuthnResponse to ' . $spentityid);
-
- /*
- * Attribute handling
- */
- $attributes = $session->getAttributes();
-
- /* Authentication processing operations. */
- if (!isset($authProcState)) {
- /* Not processed. */
- $pc = new SimpleSAML_Auth_ProcessingChain($idpmetadata,
$spMetadata->toArray(), 'idp');
-
- $authProcState = array(
- 'core:saml20-idp:requestcache' => $requestcache,
- 'ReturnURL' =>
SimpleSAML_Utilities::selfURLNoQuery(),
- 'Attributes' => $attributes,
- 'Destination' => $spMetadata->toArray(),
- 'Source' => $idpmetadata,
- 'isPassive' => $isPassive,
- SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL =>
SimpleSAML_Utilities::selfURLNoQuery(),
- );
-
- /*
- * Check whether the user has been authenticated to
this SP previously
- * during this session. If the SP is authenticated
earlier, we include
- * the timestamp to the authentication processing
filters.
- */
- $previousSSOTime =
$session->getData('saml2-idp-ssotime', $spentityid);
- if ($previousSSOTime !== NULL) {
- $authProcState['PreviousSSOTimestamp'] =
$previousSSOTime;
- }
-
- try {
- $pc->processState($authProcState);
- } catch (Exception $e) {
- handleError($e);
- }
-
- $requestcache['AuthProcState'] = $authProcState;
- }
-
- $attributes = $authProcState['Attributes'];
-
-
- /*
- * Save the time we authenticated to this SP. This can be used
later to
detect an
- * SP which reauthenticates a user very often.
- */
- $session->setData('saml2-idp-ssotime', $spentityid, time(),
- SimpleSAML_Session::DATA_TIMEOUT_LOGOUT);
-
- // Adding this service provider to the list of sessions.
- // Right now the list is used for SAML 2.0 only.
- $session->add_sp_session($spentityid);
-
- $requestID = NULL; $relayState = NULL;
- if (array_key_exists('RequestID', $requestcache)) $requestID =
$requestcache['RequestID'];
- if (array_key_exists('RelayState', $requestcache)) $relayState
=
$requestcache['RelayState'];
-
-
- /* Begin by creating the assertion. */
- $idpMetadata =
$metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
- if (array_key_exists('ConsumerURL', $requestcache)) {
- $consumerURL = $requestcache['ConsumerURL'];
- } else {
- $consumerURL =
$spMetadata->getDefaultEndpoint('AssertionConsumerService',
array(SAML2_Const::BINDING_HTTP_POST));
- $consumerURL = $consumerURL['Location'];
- }
-
- $assertion = sspmod_saml2_Message::buildAssertion($idpMetadata,
$spMetadata, $attributes, $consumerURL);
- $assertion->setInResponseTo($requestID);
-
- $nameId = $assertion->getNameId();
- $session->setSessionNameId('saml20-sp-remote', $spentityid,
$nameId);
-
- /* Maybe encrypt the assertion. */
- $assertion =
sspmod_saml2_Message::encryptAssertion($idpMetadata,
$spMetadata, $assertion);
-
- /* Create the response. */
- $ar = sspmod_saml2_Message::buildResponse($idpMetadata,
$spMetadata,
$consumerURL);
- $ar->setInResponseTo($requestID);
- $ar->setRelayState($relayState);
- $ar->setAssertions(array($assertion));
-
- $binding = new SAML2_HTTPPost();
-
$binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
- $binding->send($ar);
-
- } catch(Exception $exception) {
-
SimpleSAML_Utilities::fatalError($session->getTrackID(),
'GENERATEAUTHNRESPONSE',
$exception);
- }
-
-}
-
-
-?>
--
You received this message because you are subscribed to the Google Groups
"simpleSAMLphp commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/simplesamlphp-commits?hl=en.