diff --git a/config/config-template.php b/config/config-template.php index dfb80660c36b609587a9ec0336b4daa2f595d9a3..5f34ed7625b7a495d51aa14641298476762b8562 100644 --- a/config/config-template.php +++ b/config/config-template.php @@ -66,7 +66,11 @@ $config = array ( * cookies both at the SP and the IdP exceeds this duration. */ 'session.duration' => 8 * (60*60), // 8 hours. + 'session.requestcache' => 4 * (60*60), // 4 hours + /* + * Languages available and what language is default + */ 'language.available' => array('en', 'no'), 'language.default' => 'en', diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php index 4b85b4b547738b05fe7885be3e00329e25fdd17d..3bf9ff8c1b0bf97cde0a496a1e7e0d58539a0f5f 100644 --- a/lib/SimpleSAML/Session.php +++ b/lib/SimpleSAML/Session.php @@ -1,6 +1,4 @@ <?php - - /** * The Session class holds information about a user session, and everything attached to it. * @@ -32,10 +30,19 @@ class SimpleSAML_Session { const STATE_LOGOUTINPROGRESS = 2; const STATE_LOGGEDOUT = 3; + /** + * This variable holds the instance of the session - Singleton approach. + */ private static $instance = null; + /** + * The track id is a new random unique identifier that is generate for each session. + * This is used in the debug logs and error messages to easily track more information + * about what went wrong. + */ private $trackid = 0; + private $configuration = null; private $authnrequests = array(); @@ -60,8 +67,13 @@ class SimpleSAML_Session { // Session duration parameters private $sessionstarted = null; private $sessionduration = null; + + private $dirty = false; + - // private constructor restricts instantiaton to getInstance() + /** + * private constructor restricts instantiaton to getInstance() + */ private function __construct($protocol, SimpleSAML_XML_AuthnResponse $message = null, $authenticated = true) { $this->configuration = SimpleSAML_Configuration::getInstance(); @@ -96,6 +108,7 @@ class SimpleSAML_Session { $sh = SimpleSAML_SessionHandler::getSessionHandler(); if($sh->get('SimpleSAMLphp_SESSION') !== NULL) { self::$instance = $sh->get('SimpleSAMLphp_SESSION'); + self::$instance->dirty = false; return self::$instance; } @@ -178,22 +191,62 @@ class SimpleSAML_Session { } } - public function setShibAuthnRequest(SimpleSAML_XML_Shib13_AuthnRequest $req) { - $this->shibauthreq = $req; - } + - public function getShibAuthnRequest() { - return $this->shibauthreq; - } + + /** + * This method retrieves from session a cache of a specific Authentication Request + * The complete request is not stored, instead the values that will be needed later + * are stored in an assoc array. + * + * @param $protocol saml2 or shib13 + * @param $requestid The request id used as a key to lookup the cache. + * + * @return Returns an assoc array of cached variables associated with the + * authentication request. + */ + public function getAuthnRequest($protocol, $requestid) { + if (isset($this->authnrequests[$protocol])) { + /* + * Traverse all cached authentication requests in this session for this user using this protocol + */ + foreach ($this->authnrequests[$protocol] AS $id => $cache) { + /* + * If any of the cached requests is elder than the session.requestcache duration, then just + * simply delete it :) + */ + if ($cache['date'] < $this->configuration->getValue('session.requestcache', time() - (4*60*60) )) + unset($this->authnrequests[$protocol][$id]); + } + } + /* + * Then look if the request id that was requested exists, if so return it. + */ + if (isset($this->authnrequests[$protocol][$requestid])) { + return $this->authnrequests[$protocol][$requestid]; + } - public function setAuthnRequest($requestid, SimpleSAML_XML_SAML20_AuthnRequest $xml) { - $this->authnrequests[$requestid] = $xml; + /* + * Could not find requested ID. Throw an error. Could be that it is never set, or that it is deleted due to age. + */ + throw new Exception('Could not find cached version of authentication request with ID ' . $requestid . ' (' . $protocol . ')'); } - public function getAuthnRequest($requestid) { - return $this->authnrequests[$requestid]; + /** + * This method sets a cached assoc array to the authentication request cache storage. + * + * @param $protocol saml2 or shib13 + * @param $requestid The request id used as a key to lookup the cache. + * @param $cache The assoc array that will be stored. + */ + public function setAuthnRequest($protocol, $requestid, array $cache) { + $cache['date'] = time(); + $this->authnrequests[$protocol][$requestid] = $cache; + } + + public function setAuthnResponse(SimpleSAML_XML_AuthnResponse $xml) { $this->authnresponse = $xml; } @@ -294,7 +347,14 @@ class SimpleSAML_Session { public function setAttribute($name, $value) { $this->attributes[$name] = $value; } - + + + /** + * Is this session modified since loaded? + */ + public function isModified() { + return $this->dirty; + } } ?> \ No newline at end of file diff --git a/lib/SimpleSAML/XML/SAML20/AuthnRequest.php b/lib/SimpleSAML/XML/SAML20/AuthnRequest.php index ead9afa386a54f4137259d9642c238f76c3b3067..b53a18e23ebc1c53ffd6b4ba4ba64f5dc8618247 100644 --- a/lib/SimpleSAML/XML/SAML20/AuthnRequest.php +++ b/lib/SimpleSAML/XML/SAML20/AuthnRequest.php @@ -1,21 +1,15 @@ <?php - - -/** - * SimpleSAMLphp - * - * PHP versions 4 and 5 - * - * LICENSE: See the COPYING file included in this distribution. - * - * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> - */ require_once('SimpleSAML/Configuration.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); /** - * Configuration of SimpleSAMLphp + * The Shibboleth 1.3 Authentication Request. Not part of SAML 1.1, + * but an extension using query paramters no XML. + * + * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @package simpleSAMLphp + * @version $Id$ */ class SimpleSAML_XML_SAML20_AuthnRequest { @@ -27,7 +21,7 @@ class SimpleSAML_XML_SAML20_AuthnRequest { private $relayState = null; - const PROTOCOL = 'urn:oasis:names:tc:SAML:2.0'; + const PROTOCOL = 'saml2'; function __construct(SimpleSAML_Configuration $configuration, SimpleSAML_Metadata_MetaDataStorageHandler $metadatastore) { @@ -110,7 +104,7 @@ class SimpleSAML_XML_SAML20_AuthnRequest { return $requestid; */ } - + /* public function createSession() { @@ -122,15 +116,10 @@ class SimpleSAML_XML_SAML20_AuthnRequest { } $session->setAuthnRequest($this->getRequestID(), $this); - - /* - if (isset($this->relayState)) { - $session->setRelayState($this->relayState); - } - */ + return $session; } - + */ public function generate($spentityid, $destination) { $md = $this->metadata->getMetaData($spentityid); diff --git a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php index 65ed360ebeab4364114c2fb8f60be02e7ae716e0..1876ebc2ac25c97171f5744049eb47dd13636af3 100644 --- a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php +++ b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php @@ -24,14 +24,6 @@ require_once('xmlseclibs.php'); */ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { - private $configuration = null; - private $metadata = 'default.php'; - - private $message = null; - private $dom; - private $relayState = null; - - private $validIDs = null; const PROTOCOL = 'urn:oasis:names:tc:SAML:2.0'; @@ -105,12 +97,15 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { throw new Exception("Unable to validate Signature"); } + foreach ($refids AS $key => $value) { + $refids[$key] = str_replace('#', '', $value); + } + $this->validIDs = $refids; return true; } - - + function validateCertFingerprint($objKey) { @@ -229,9 +224,7 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { $end = $node->getAttribute("NotOnOrAfter"); if (! SimpleSAML_Utilities::checkDateConditions($start, $end)) { - error_log( " Date check failed ... (from $start to $end)"); - - return $attributes; + throw new Exception("Date check failed (between $start and $end). Check if the clocks on the SP and IdP are synchronized. Alternatively you can get this message, when you move back in history or refresh an old page."); } } @@ -332,12 +325,12 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { } - /* This function retrieves the ID of the request this response is a + /** + * This function retrieves the ID of the request this response is a * response to. This ID is stored in the InResponseTo attribute of the * top level DOM element. * - * Returns: - * The ID of the request this response is a response to, or NULL if + * @return The ID of the request this response is a response to, or NULL if * we don't know. */ public function getInResponseTo() { @@ -466,17 +459,16 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { } - /* This function converts an array of attribute values into an + /** + * This function converts an array of attribute values into an * encoded saml:Attribute element which should go into the * AuthnResponse. The data can optionally be base64 encoded. * - * Parameters: - * $name Name of this attribute. - * $values Array with the values of this attribute. - * $base64 Enable base64 encoding of attribute values. + * @param $name Name of this attribute. + * @param $values Array with the values of this attribute. + * @param $base64 Enable base64 encoding of attribute values. * - * Returns: - * String containing the encoded saml:attribute value for this + * @return String containing the encoded saml:attribute value for this * attribute. */ private static function enc_attribute($name, $values, $base64 = false) { @@ -495,7 +487,6 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { $text . '</saml:AttributeValue>'; } - $ret .= '</saml:Attribute>'; return $ret; diff --git a/lib/SimpleSAML/XML/Shib13/AuthnRequest.php b/lib/SimpleSAML/XML/Shib13/AuthnRequest.php index 053319c41271e2e084ce97816093fb33a175f231..1fe6972aa9ffd9825ba0b98dc8ae9a1b1339603b 100644 --- a/lib/SimpleSAML/XML/Shib13/AuthnRequest.php +++ b/lib/SimpleSAML/XML/Shib13/AuthnRequest.php @@ -1,21 +1,15 @@ <?php - -/** - * SimpleSAMLphp - * - * PHP versions 4 and 5 - * - * LICENSE: See the COPYING file included in this distribution. - * - * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> - */ - require_once('SimpleSAML/Configuration.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); /** - * Configuration of SimpleSAMLphp + * The Shibboleth 1.3 Authentication Request. Not part of SAML 1.1, + * but an extension using query paramters no XML. + * + * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @package simpleSAMLphp + * @version $Id$ */ class SimpleSAML_XML_Shib13_AuthnRequest { @@ -29,7 +23,7 @@ class SimpleSAML_XML_Shib13_AuthnRequest { private $requestid = null; - const PROTOCOL = 'shibboleth'; + const PROTOCOL = 'shib13'; function __construct(SimpleSAML_Configuration $configuration, SimpleSAML_Metadata_MetaDataStorageHandler $metadatastore) { @@ -83,25 +77,7 @@ class SimpleSAML_XML_Shib13_AuthnRequest { public function getRequestID() { return $this->requestid; } - - public function createSession() { - - $session = SimpleSAML_Session::getInstance(); - - if (!isset($session)) { - SimpleSAML_Session::init(self::PROTOCOL, null, false); - $session = SimpleSAML_Session::getInstance(); - } - $session->setShibAuthnRequest($this); - - /* - if (isset($this->relayState)) { - $session->setRelayState($this->relayState); - } - */ - return $session; - } public function createRedirect($destination) { $idpmetadata = $this->metadata->getMetaData($destination, 'shib13-idp-remote'); diff --git a/www/saml2/idp/SSOService.php b/www/saml2/idp/SSOService.php index 7c2b82aa5480675cb38a2173f45db1142676550a..31d590aa5a9cd5c0e48f0b033c38aa27b62b8cca 100644 --- a/www/saml2/idp/SSOService.php +++ b/www/saml2/idp/SSOService.php @@ -1,9 +1,16 @@ <?php - +/** + * The SSOService is part of the SAML 2.0 IdP code, and it receives incomming Authentication Requests + * from a SAML 2.0 SP, parses, and process it, and then authenticates the user and sends the user back + * to the SP with an Authentication Response. + * + * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @package simpleSAMLphp + * @version $Id$ + */ require_once('../../../www/_include.php'); - require_once('SimpleSAML/Utilities.php'); require_once('SimpleSAML/Session.php'); require_once('SimpleSAML/Logger.php'); @@ -29,7 +36,14 @@ $requestid = null; $logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'EVENT', 'Access', 'Accessing SAML 2.0 IdP endpoint SSOService'); - +/* + * If the SAMLRequest query parameter is set, we got an incomming 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($_GET['SAMLRequest'])) { @@ -37,16 +51,25 @@ if (isset($_GET['SAMLRequest'])) { $binding = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata); $authnrequest = $binding->decodeRequest($_GET); - $session = $authnrequest->createSession(); + //$session = $authnrequest->createSession(); $requestid = $authnrequest->getRequestID(); + /* + * Create an assoc array of the request to store in the session cache. + */ + $requestcache = array( + 'Issuer' => $authnrequest->getIssuer() + ); + if ($relaystate = $authnrequest->getRelayState() ) + $requestcache['RelayState'] = $relaystate; + + $session->setAuthnRequest('saml2', $requestid, $requestcache); + if ($binding->validateQuery($authnrequest->getIssuer(),'IdP')) { $logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'AuthnRequest', $requestid, 'Valid signature found'); } - $session->setAuthnRequest($requestid, $authnrequest); - $logger->log(LOG_NOTICE, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'AuthnRequest', array($authnrequest->getIssuer(), $requestid), 'Incomming Authentication request'); @@ -63,19 +86,26 @@ if (isset($_GET['SAMLRequest'])) { exit(0); } +/* + * If we did not get an incomming 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 { $requestid = $_GET['RequestID']; - $session = SimpleSAML_Session::getInstance(); - $authnrequest = $session->getAuthnRequest($requestid); + $requestcache = $session->getAuthnRequest('saml2', $requestid); $logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'EVENT', $requestid, 'Got incomming RequestID'); - - if (!$authnrequest) throw new Exception('Could not retrieve cached RequestID = ' . $requestid); + if (!$requestcache) throw new Exception('Could not retrieve cached RequestID = ' . $requestid); } catch(Exception $exception) { @@ -90,24 +120,31 @@ if (isset($_GET['SAMLRequest'])) { } - - /* - $authnrequest = new SimpleSAML_XML_SAML20_AuthnRequest($config, $metadata); - $authnrequest->setXML($authnrequestXML); - */ - - } else { - - echo 'You must either provide a SAML Request message or a RequestID on this interface.'; + /* + * We did neither get a request or a requestID as a parameter. Then throw an error. + */ + $et = new SimpleSAML_XHTML_Template($config, 'error.php'); + + $et->data['header'] = 'No parameters found'; + $et->data['message'] = 'You must either provide a SAML Request message or a RequestID on this interface.'; + $et->data['e'] = $exception; + + $et->show(); exit(0); - } - - +/* + * As we have passed the code above, we have an accociated 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 (!$session->isAuthenticated() ) { $logger->log(LOG_NOTICE, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'AuthNext', $idpmeta['auth'], @@ -119,12 +156,16 @@ if (!$session->isAuthenticated() ) { SimpleSAML_Utilities::redirect($authurl, array('RelayState' => $relaystate)); + +/* + * We got an request, and we hav a valid session. Then we send an AuthenticationResponse back to the + * service. + */ } else { try { - - $spentityid = $authnrequest->getIssuer(); + $spentityid = $requestcache['Issuer']; $spmetadata = $metadata->getMetaData($spentityid, 'saml20-sp-remote'); /* @@ -151,19 +192,16 @@ if (!$session->isAuthenticated() ) { $logger->log(LOG_NOTICE, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'ConsentOK', '-', 'Got consent from user'); - } } // 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); - - $logger->log(LOG_NOTICE, $session->getTrackID(), 'SAML2.0', 'IdP.SSOService', 'AuthnResponse', $spentityid, 'Sending back AuthnResponse'); - /* * Filtering attributes. @@ -185,9 +223,9 @@ if (!$session->isAuthenticated() ) { // Sending the AuthNResponse using HTTP-Post SAML 2.0 binding $httppost = new SimpleSAML_Bindings_SAML20_HTTPPost($config, $metadata); $httppost->sendResponse($authnResponseXML, - $idpentityid, $authnrequest->getIssuer(), $authnrequest->getRelayState()); - - + $idpentityid, $spentityid, + isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null + ); } catch(Exception $exception) { @@ -198,7 +236,6 @@ if (!$session->isAuthenticated() ) { $et->data['e'] = $exception; $et->show(); - } } diff --git a/www/saml2/sp/AssertionConsumerService.php b/www/saml2/sp/AssertionConsumerService.php index 3b327e4bcc6540117be38f64c6568a9f93a32dd6..d1d5da804061270722496dab51cdae3409d02bce 100644 --- a/www/saml2/sp/AssertionConsumerService.php +++ b/www/saml2/sp/AssertionConsumerService.php @@ -44,7 +44,7 @@ try { if (isset($relayState)) { SimpleSAML_Utilities::redirect($relayState); } else { - echo 'Could not find RelayState parameter, you are stucked here.'; + throw new Exception('Could not find RelayState parameter, you are stucked here.'); } } else { throw new Exception('Unkown error. Could not get session.'); diff --git a/www/shib13/idp/SSOService.php b/www/shib13/idp/SSOService.php index 44c3e6ce1fa30f06f9cd778ec3f7c7390c1b7656..f5ce87b63c6f6f8ae8d727d33812ca0eb7124d2d 100644 --- a/www/shib13/idp/SSOService.php +++ b/www/shib13/idp/SSOService.php @@ -1,11 +1,19 @@ <?php - +/** + * The SSOService is part of the Shibboleth 1.3 IdP code, and it receives incomming Authentication Requests + * from a Shibboleth 1.3 SP, parses, and process it, and then authenticates the user and sends the user back + * to the SP with an Authentication Response. + * + * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @package simpleSAMLphp + * @version $Id$ + */ require_once('../../../www/_include.php'); - require_once('SimpleSAML/Utilities.php'); require_once('SimpleSAML/Session.php'); +require_once('SimpleSAML/Logger.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); require_once('SimpleSAML/XML/AttributeFilter.php'); require_once('SimpleSAML/XML/Shib13/AuthnRequest.php'); @@ -17,14 +25,25 @@ require_once('SimpleSAML/XHTML/Template.php'); $config = SimpleSAML_Configuration::getInstance(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); +$session = SimpleSAML_Session::getInstance(true); + +$logger = new SimpleSAML_Logger(); $idpentityid = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted'); $idpmeta = $metadata->getMetaDataCurrent('shib13-idp-hosted'); $requestid = null; -$session = null; +$logger->log(LOG_INFO, $session->getTrackID(), 'Shib1.3', 'IdP.SSOService', 'EVENT', 'Access', 'Accessing Shibboleth 1.3 IdP endpoint SSOService'); +/* + * If the shire query parameter is set, we got an incomming 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($_GET['shire'])) { @@ -32,13 +51,25 @@ if (isset($_GET['shire'])) { $authnrequest = new SimpleSAML_XML_Shib13_AuthnRequest($config, $metadata); $authnrequest->parseGet($_GET); - $session = $authnrequest->createSession(); + //$session = $authnrequest->createSession(); $requestid = $authnrequest->getRequestID(); //$session->setShibAuthnRequest($authnrequest); - + + + /* + * Create an assoc array of the request to store in the session cache. + */ + $requestcache = array( + 'Issuer' => $authnrequest->getIssuer(), + 'shire' => $authnrequest->getShire(), + ); + if ($relaystate = $authnrequest->getRelayState() ) + $requestcache['RelayState'] = $relaystate; + + $session->setAuthnRequest('shib13', $requestid, $requestcache); } catch(Exception $exception) { @@ -50,21 +81,31 @@ if (isset($_GET['shire'])) { $et->data['e'] = $exception; $et->show(); - + exit(0); } -} elseif(isset($_GET['RequestID'])) { - - +/* + * If we did not get an incomming 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 { $requestid = $_GET['RequestID']; - $session = SimpleSAML_Session::getInstance(); - $authnrequest = $session->getShibAuthnRequest(); + + $requestcache = $session->getAuthnRequest('shib13', $requestid); - if (!$authnrequest) throw new Exception('Could not retrieve cached RequestID = ' . $requestid); + $logger->log(LOG_INFO, $session->getTrackID(), 'Shib1.3', 'IdP.SSOService', 'EVENT', $requestid, 'Got incomming RequestID'); + if (!$requestcache) throw new Exception('Could not retrieve cached RequestID = ' . $requestid); + } catch(Exception $exception) { $et = new SimpleSAML_XHTML_Template($config, 'error.php'); @@ -74,33 +115,46 @@ if (isset($_GET['shire'])) { $et->data['e'] = $exception; $et->show(); - } - - - /* - $authnrequest = new SimpleSAML_XML_SAML20_AuthnRequest($config, $metadata); - $authnrequest->setXML($authnrequestXML); - */ - - } else { - - echo 'You must either provide a SAML Request message or a RequestID on this interface.'; + /* + * We did neither get a request or a requestID as a parameter. Then throw an error. + */ + $et = new SimpleSAML_XHTML_Template($config, 'error.php'); + + $et->data['header'] = 'No parameters found'; + $et->data['message'] = 'You must either provide a Shibboleth Request message or a RequestID on this interface.'; + $et->data['e'] = $exception; + + $et->show(); exit(0); } - +/* + * As we have passed the code above, we have an accociated 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 (!$session->isAuthenticated() ) { $relaystate = SimpleSAML_Utilities::selfURLNoQuery() . '?RequestID=' . urlencode($requestid); $authurl = SimpleSAML_Utilities::addURLparameter('/' . $config->getValue('baseurlpath') . $idpmeta['auth'], 'RelayState=' . urlencode($relaystate)); SimpleSAML_Utilities::redirect($authurl); + + +/* + * We got an request, and we hav a valid session. Then we send an AuthenticationResponse back to the + * service. + */ } else { try { @@ -110,7 +164,7 @@ if (!$session->isAuthenticated() ) { //$session->setAttribute('eduPersonAffiliation', array('student')); - $spentityid = $authnrequest->getIssuer(); + $spentityid = $requestcache['Issuer']; $spmetadata = $metadata->getMetaData($spentityid, 'shib13-sp-remote'); /* @@ -130,7 +184,7 @@ if (!$session->isAuthenticated() ) { // Generating a Shibboleth 1.3 Response. $ar = new SimpleSAML_XML_Shib13_AuthnResponse($config, $metadata); - $authnResponseXML = $ar->generate($idpentityid, $authnrequest->getIssuer(), + $authnResponseXML = $ar->generate($idpentityid, $requestcache['Issuer'], $requestid, null, $filteredattributes); @@ -142,13 +196,13 @@ if (!$session->isAuthenticated() ) { //echo 'Relaystate[' . $authnrequest->getRelayState() . ']'; - $issuer = $authnrequest->getIssuer(); - $shire = $authnrequest->getShire(); + $issuer = $requestcache['Issuer']; + $shire = $requestcache['shire']; if ($issuer == null || $issuer == '') throw new Exception('Could not retrieve issuer of the AuthNRequest (ProviderID)'); $httppost->sendResponse($authnResponseXML, - $idpentityid, $issuer, $authnrequest->getRelayState(), $shire); + $idpentityid, $issuer, isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null, $shire); } catch(Exception $exception) { diff --git a/www/shib13/sp/initSSO.php b/www/shib13/sp/initSSO.php index 106ae18f937b984d05230c83c6f7a5ed4e70ed3a..55a7723fb8b72ec5f2c52577d9a6fe4849b0e54a 100644 --- a/www/shib13/sp/initSSO.php +++ b/www/shib13/sp/initSSO.php @@ -8,9 +8,6 @@ require_once('SimpleSAML/Session.php'); require_once('SimpleSAML/XHTML/Template.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); require_once('SimpleSAML/XML/Shib13/AuthnRequest.php'); -//require_once('SimpleSAML/XML/SAML20/AuthnResponse.php'); -//require_once('SimpleSAML/Bindings/SAML20/HTTPRedirect.php'); -//require_once('SimpleSAML/Bindings/SAML20/HTTPPost.php'); $config = SimpleSAML_Configuration::getInstance(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); @@ -41,9 +38,10 @@ try { exit(0); } + + if (!isset($session) || !$session->isValid() ) { - if ($idpentityid == null) { $returnURL = urlencode(SimpleSAML_Utilities::selfURL()); @@ -77,7 +75,6 @@ if (!isset($session) || !$session->isValid() ) { } else { - $relaystate = $session->getRelayState(); if (isset($relaystate) && !empty($relaystate)) { @@ -96,10 +93,6 @@ if (!isset($session) || !$session->isValid() ) { } -#print_r($metadata->getMetaData('sam.feide.no')); -#print_r($req); - -//echo 'Location: ' . $relaystate; -?> +?> \ No newline at end of file