From 366ad253e9be07c4c84042737b351e58d0016946 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Mon, 20 Sep 2010 08:40:23 +0000 Subject: [PATCH] saml:SP: Process multiple assertions in response. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2557 44740490-163a-0410-bde0-09ae8108e29a --- modules/saml/www/sp/saml2-acs.php | 66 +++++++++++++++++++------------ 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php index 35fc6f60f..7fa449357 100644 --- a/modules/saml/www/sp/saml2-acs.php +++ b/modules/saml/www/sp/saml2-acs.php @@ -47,41 +47,57 @@ SimpleSAML_Logger::debug('Received SAML2 Response from ' . var_export($idp, TRUE $idpMetadata = $source->getIdPmetadata($idp); try { - $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]; + $assertions = sspmod_saml_Message::processResponse($spMetadata, $idpMetadata, $response); } catch (sspmod_saml_Error $e) { /* The status of the response wasn't "success". */ $e = $e->toException(); SimpleSAML_Auth_State::throwException($state, $e); } -/* Check for duplicate assertion (replay attack). */ -$store = SimpleSAML_Store::getInstance(); -if ($store !== FALSE) { - $aID = $assertion->getId(); - if ($store->get('saml.AssertionReceived', $aID) !== NULL) { - $e = new SimpleSAML_Error_Exception('Received duplicate assertion.'); - SimpleSAML_Auth_State::throwException($state, $e); - } - $notOnOrAfter = $assertion->getNotOnOrAfter(); - if ($notOnOrAfter === NULL) { - $notOnOrAfter = time() + 24*60*60; - } else { - $notOnOrAfter += 60; /* We allow 60 seconds clock skew, so add it here also. */ +$authenticatingAuthority = NULL; +$nameId = NULL; +$sessionIndex = NULL; +$expire = NULL; +$attributes = array(); +foreach ($assertions as $assertion) { + + /* Check for duplicate assertion (replay attack). */ + $store = SimpleSAML_Store::getInstance(); + if ($store !== FALSE) { + $aID = $assertion->getId(); + if ($store->get('saml.AssertionReceived', $aID) !== NULL) { + $e = new SimpleSAML_Error_Exception('Received duplicate assertion.'); + SimpleSAML_Auth_State::throwException($state, $e); + } + + $notOnOrAfter = $assertion->getNotOnOrAfter(); + if ($notOnOrAfter === NULL) { + $notOnOrAfter = time() + 24*60*60; + } else { + $notOnOrAfter += 60; /* We allow 60 seconds clock skew, so add it here also. */ + } + + $store->set('saml.AssertionReceived', $aID, TRUE, $notOnOrAfter); } - $store->set('saml.AssertionReceived', $aID, TRUE, $notOnOrAfter); -} + if ($authenticatingAuthority === NULL) { + $authenticatingAuthority = $assertion->getAuthenticatingAuthority(); + } + if ($nameId === NULL) { + $nameId = $assertion->getNameId(); + } + if ($sessionIndex === NULL) { + $sessionIndex = $assertion->getSessionIndex(); + } + if ($expire === NULL) { + $expire = $assertion->getSessionNotOnOrAfter(); + } -$nameId = $assertion->getNameId(); -$sessionIndex = $assertion->getSessionIndex(); + $attributes = array_merge($attributes, $assertion->getAttributes()); +} -$expire = $assertion->getSessionNotOnOrAfter(); if ($expire === NULL) { /* Just expire the logout associtaion 24 hours into the future. */ $expire = time() + 24*60*60; @@ -98,9 +114,9 @@ $logoutState = array( 'saml:logout:SessionIndex' => $sessionIndex, ); $state['LogoutState'] = $logoutState; -$state['saml:AuthenticatingAuthority'] = $assertion->getAuthenticatingAuthority(); +$state['saml:AuthenticatingAuthority'] = $authenticatingAuthority; $state['saml:AuthenticatingAuthority'][] = $idp; $state['PersistentAuthData'][] = 'saml:AuthenticatingAuthority'; -$source->handleResponse($state, $idp, $assertion->getAttributes()); +$source->handleResponse($state, $idp, $attributes); assert('FALSE'); -- GitLab