diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php index b26bc16ada402106ae910aaf79947ea40ed0c503..c69e8f233a9061a166101f56f3c5b01940c875f2 100644 --- a/lib/SimpleSAML/SessionHandler.php +++ b/lib/SimpleSAML/SessionHandler.php @@ -135,7 +135,10 @@ abstract class SessionHandler */ private static function createSessionHandler(): void { - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + + $store = StoreFactory::getInstance($storeType); if ($store === false) { self::$sessionHandler = new SessionHandlerPHP(); } else { diff --git a/lib/SimpleSAML/Store/StoreFactory.php b/lib/SimpleSAML/Store/StoreFactory.php index f3aa7ea764ece59d0ce3e8d8aad35e7ffc25dab1..9f3c93f49b3cb722037deb9dbe639928c52571ef 100644 --- a/lib/SimpleSAML/Store/StoreFactory.php +++ b/lib/SimpleSAML/Store/StoreFactory.php @@ -30,19 +30,17 @@ abstract class StoreFactory implements Utils\ClearableState /** * Retrieve our singleton instance. * + * @param string $storeType The type of store we need to instantiate * @return \SimpleSAML\Store\StoreInterface|false The data store, or false if it isn't enabled. * * @throws \SimpleSAML\Error\CriticalConfigurationError */ - public static function getInstance() + public static function getInstance(string $storeType) { if (self::$instance !== null) { return self::$instance; } - $config = Configuration::getInstance(); - $storeType = $config->getString('store.type', 'phpsession'); - switch ($storeType) { case 'phpsession': // we cannot support advanced features with the PHP session store @@ -62,6 +60,7 @@ abstract class StoreFactory implements Utils\ClearableState try { $className = Module::resolveClass($storeType, 'StoreInterface'); } catch (Exception $e) { + $config = Configuration::getInstance(); $c = $config->toArray(); $c['store.type'] = 'phpsession'; throw new Error\CriticalConfigurationError( diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php index 0bfb57c54a00420040a0995d7589ef1d00afda9e..93e40e92298dac4b7cf61961321c58bcd75e803f 100644 --- a/modules/saml/lib/Auth/Source/SP.php +++ b/modules/saml/lib/Auth/Source/SP.php @@ -386,7 +386,10 @@ class SP extends \SimpleSAML\Auth\Source */ private function getSLOEndpoints(): array { - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + + $store = StoreFactory::getInstance($storeType); $bindings = $this->metadata->getArray( 'SingleLogoutServiceBinding', [ diff --git a/modules/saml/lib/IdP/SQLNameID.php b/modules/saml/lib/IdP/SQLNameID.php index 604da6d2075afe75a072cdddf847e5de7bcc07d0..7a43e101698a44428b4c999eaaca2b87841eca71 100644 --- a/modules/saml/lib/IdP/SQLNameID.php +++ b/modules/saml/lib/IdP/SQLNameID.php @@ -158,12 +158,16 @@ class SQLNameID */ private static function getStore(): Store\SQLStore { - $store = StoreFactory::getInstance(); - if (!($store instanceof Store\SQLStore)) { - throw new Error\Exception( - 'SQL NameID store requires SimpleSAMLphp to be configured with a SQL datastore.' - ); - } + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + + $store = StoreFactory::getInstance($storeType); + Assert::isInstanceOf( + $store, + Store\SQLStore::class, + 'SQL NameID store requires SimpleSAMLphp to be configured with a SQL datastore.', + Error\Exception::class + ); return $store; } diff --git a/modules/saml/lib/SP/LogoutStore.php b/modules/saml/lib/SP/LogoutStore.php index b021f2420cf06f69bd5186839fa77a19d584d046..e6205ce6e7c35c788fc76c8ad3ab0be3059f882b 100644 --- a/modules/saml/lib/SP/LogoutStore.php +++ b/modules/saml/lib/SP/LogoutStore.php @@ -8,6 +8,7 @@ use Exception; use PDO; use SAML2\XML\saml\NameID; use SimpleSAML\Assert\Assert; +use SimpleSAML\Configuration; use SimpleSAML\Logger; use SimpleSAML\Session; use SimpleSAML\Store; @@ -209,7 +210,10 @@ class LogoutStore $sessionIndex = $randomUtils->generateID(); } - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + + $store = StoreFactory::getInstance($storeType); if ($store === false) { // We don't have a datastore. return; @@ -245,7 +249,10 @@ class LogoutStore */ public static function logoutSessions(string $authId, NameID $nameId, array $sessionIndexes) { - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + + $store = StoreFactory::getInstance($storeType); if ($store === false) { // We don't have a datastore return false; diff --git a/modules/saml/www/sp/metadata.php b/modules/saml/www/sp/metadata.php index 473117602124c0a4dccc86ae930d444e0e40a79e..4a9fabcb55afb8b5ee72b0d11ec8b0816456818c 100644 --- a/modules/saml/www/sp/metadata.php +++ b/modules/saml/www/sp/metadata.php @@ -37,7 +37,9 @@ if (!($source instanceof Module\saml\Auth\Source\SP)) { $entityId = $source->getEntityId(); $spconfig = $source->getMetadata(); $metaArray20 = $source->getHostedMetadata(); -$store = StoreFactory::getInstance(); + +$storeType = $config->getString('store.type', 'phpsession'); +$store = StoreFactory::getInstance($storeType); $metaBuilder = new Metadata\SAMLBuilder($entityId); $metaBuilder->addMetadataSP20($metaArray20, $source->getSupportedProtocols()); diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php index 56bc5eedbabc810f7793feeffcc83e25d87ad433..23aad339125a78136261b8a1ea446cdfa3fe9fa4 100644 --- a/modules/saml/www/sp/saml2-acs.php +++ b/modules/saml/www/sp/saml2-acs.php @@ -10,6 +10,7 @@ use SAML2\HTTPArtifact; use SAML2\Response; use SimpleSAML\Assert\Assert; use SimpleSAML\Auth; +use SimpleSAML\Configuration; use SimpleSAML\Error; use SimpleSAML\Module; use SimpleSAML\Logger; @@ -159,7 +160,10 @@ $foundAuthnStatement = false; foreach ($assertions as $assertion) { // check for duplicate assertion (replay attack) - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + + $store = StoreFactory::getInstance($storeType); if ($store !== false) { $aID = $assertion->getId(); if ($store->get('saml.AssertionReceived', $aID) !== null) { diff --git a/tests/lib/SimpleSAML/Store/StoreFactoryTest.php b/tests/lib/SimpleSAML/Store/StoreFactoryTest.php index 347cf399200241558895a40f73d19a7d6f6a29c6..3164d5f1c67dfe7cebaa00870f39fd53b16cd538 100644 --- a/tests/lib/SimpleSAML/Store/StoreFactoryTest.php +++ b/tests/lib/SimpleSAML/Store/StoreFactoryTest.php @@ -31,8 +31,11 @@ class StoreFactoryTest extends TestCase { Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + /** @var false $store */ - $store = StoreFactory::getInstance(); + $store = StoreFactory::getInstance($storeType); $this->assertFalse($store); } @@ -43,10 +46,15 @@ class StoreFactoryTest extends TestCase */ public function phpSessionStore(): void { - Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); + Configuration::loadFromArray([ + 'store.type' => 'phpsession', + ], '[ARRAY]', 'simplesaml'); + + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); /** @var false $store */ - $store = StoreFactory::getInstance(); + $store = StoreFactory::getInstance($storeType); $this->assertFalse($store); } @@ -61,7 +69,10 @@ class StoreFactoryTest extends TestCase 'store.type' => 'memcache', ], '[ARRAY]', 'simplesaml'); - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); + + $store = StoreFactory::getInstance($storeType); $this->assertInstanceOf(Store\MemcacheStore::class, $store); } @@ -77,8 +88,11 @@ class StoreFactoryTest extends TestCase 'store.redis.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); + /** @psalm-var \SimpleSAML\Store\RedisStore $store */ - $store = StoreFactory::getInstance(); + $store = StoreFactory::getInstance($storeType); $store->redis = $this->getMockBuilder(Client::class) ->setMethods(['get', 'set', 'setex', 'del', 'disconnect', '__destruct']) ->disableOriginalConstructor() @@ -99,7 +113,10 @@ class StoreFactoryTest extends TestCase 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); + + $store = StoreFactory::getInstance($storeType); $this->assertInstanceOf(Store\SQLStore::class, $store); } @@ -116,7 +133,10 @@ class StoreFactoryTest extends TestCase 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); + + $store = StoreFactory::getInstance($storeType); $this->assertInstanceOf(Store\SQLStore::class, $store); } @@ -134,7 +154,10 @@ class StoreFactoryTest extends TestCase 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); - StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); + + StoreFactory::getInstance($storeType); } @@ -143,8 +166,10 @@ class StoreFactoryTest extends TestCase protected function tearDown(): void { $config = Configuration::getInstance(); + $storeType = $config->getString('store.type', 'phpsession'); + /** @var \SimpleSAML\Store\StoreInterface $store */ - $store = StoreFactory::getInstance(); + $store = StoreFactory::getInstance($storeType); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, StoreFactory::class); diff --git a/tests/modules/saml/lib/IdP/SQLNameIDTest.php b/tests/modules/saml/lib/IdP/SQLNameIDTest.php index 098a687029ec5315ff7b73636613e372783e18b9..e12629ae73eb48ea695a8242d5a5c1962139ee1d 100644 --- a/tests/modules/saml/lib/IdP/SQLNameIDTest.php +++ b/tests/modules/saml/lib/IdP/SQLNameIDTest.php @@ -46,8 +46,9 @@ class SQLNameIDTest extends TestCase ], '[ARRAY]', 'simplesaml'); $this->addGetDelete(); $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); /** @var \SimpleSAML\Store\StoreInterface $store */ - $store = StoreFactory::getInstance(); + $store = StoreFactory::getInstance($storeType); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, StoreFactory::class); } @@ -62,13 +63,16 @@ class SQLNameIDTest extends TestCase Configuration::loadFromArray([ 'store.type' => 'memcache', ], '[ARRAY]', 'simplesaml'); - $store = StoreFactory::getInstance(); + $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); + $store = StoreFactory::getInstance($storeType); $this->assertInstanceOf(Store\MemcacheStore::class, $store); $this->expectException(Error\Exception::class); $this->addGetDelete(); $config = Configuration::getInstance(); + $storeType = $config->getString('store.type'); /** @var \SimpleSAML\Store\StoreInterface $store */ - $store = StoreFactory::getInstance(); + $store = StoreFactory::getInstance($storeType); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, StoreFactory::class); } diff --git a/www/saml2/idp/ArtifactResolutionService.php b/www/saml2/idp/ArtifactResolutionService.php index be3d121db3c86e00224b9bbecd5a781dc569c823..5e91f3fc3d715dc592c41cc930f6db96c7bd2372 100644 --- a/www/saml2/idp/ArtifactResolutionService.php +++ b/www/saml2/idp/ArtifactResolutionService.php @@ -35,7 +35,8 @@ if (!$idpMetadata->getBoolean('saml20.sendartifact', false)) { throw new Error\Error('NOACCESS'); } -$store = StoreFactory::getInstance(); +$storeType = $config->getString('store.type', 'phpsession'); +$store = StoreFactory::getInstance($storeType); if ($store === false) { throw new Exception('Unable to send artifact without a datastore configured.'); }