Skip to content

Commit 44b99a6

Browse files
committed
Migrate samlp:Scoping + sub-elements to new interface
1 parent 4bcc440 commit 44b99a6

3 files changed

Lines changed: 63 additions & 38 deletions

File tree

modules/saml/src/Auth/Source/SP.php

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use SimpleSAML\SAML2\Exception\Protocol\{NoAvailableIDPException, NoPassiveException, NoSupportedIDPException};
1515
use SimpleSAML\SAML2\XML\md\ContactPerson;
1616
use SimpleSAML\SAML2\XML\saml\NameID;
17-
use SimpleSAML\SAML2\XML\samlp\Extensions;
17+
use SimpleSAML\SAML2\XML\samlp\{Extensions, IDPEntry, IDPList, RequesterID, Scoping};
1818
use SimpleSAML\Store\StoreFactory;
1919
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
2020
use Symfony\Component\HttpFoundation\{RedirectResponse, Request, Response};
@@ -565,39 +565,50 @@ private function startSSO2(Configuration $idpMetadata, array $state): Response
565565
$ar->setNameIdPolicy($state['saml:NameIDPolicy']);
566566
}
567567

568+
$proxyCount = $idpList = null;
568569
$requesterID = [];
569570

570571
/* Only check for real info for Scoping element if we are going to send Scoping element */
571572
if ($this->disable_scoping !== true && $idpMetadata->getOptionalBoolean('disable_scoping', false) !== true) {
573+
$idpEntry = [];
572574
if (isset($state['IDPList'])) {
573-
$ar->setIDPList($state['IDPList']);
575+
$idpList = $state['IDPList'];
574576
} elseif (!empty($this->metadata->getOptionalArray('IDPList', []))) {
575-
$ar->setIDPList($this->metadata->getArray('IDPList'));
577+
foreach ($this->metadata->getArray('IDPList') as $entry) {
578+
$idpEntry[] = new IDPEntry($entry);
579+
}
580+
$idpList = new IDPList($idpEntry);
576581
} elseif (!empty($idpMetadata->getOptionalArray('IDPList', []))) {
577-
$ar->setIDPList($idpMetadata->getArray('IDPList'));
582+
foreach ($idpMetadata->getArray('IDPList') as $entry) {
583+
$idpEntry[] = new IDPEntry($entry);
584+
}
585+
$idpList = new IDPList($idpEntry);
578586
}
579587

580588
if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] !== null) {
581-
$ar->setProxyCount($state['saml:ProxyCount']);
589+
$proxyCount = $state['saml:ProxyCount'];
582590
} elseif ($idpMetadata->hasValue('ProxyCount')) {
583-
$ar->setProxyCount($idpMetadata->getInteger('ProxyCount'));
591+
$proxyCount = $idpMetadata->getInteger('ProxyCount');
584592
} elseif ($this->metadata->hasValue('ProxyCount')) {
585-
$ar->setProxyCount($this->metadata->getInteger('ProxyCount'));
593+
$proxyCount = $this->metadata->getInteger('ProxyCount');
586594
}
587595

588596
$requesterID = [];
589597
if (isset($state['saml:RequesterID'])) {
590-
$requesterID = $state['saml:RequesterID'];
598+
foreach ($state['saml:RequesterID'] as $requesterId) {
599+
$requesterID[] = new RequesterID($requesterId);
600+
}
591601
}
592602

593603
if (isset($state['core:SP'])) {
594-
$requesterID[] = $state['core:SP'];
604+
$requesterID[] = new RequesterID($state['core:SP']);
595605
}
596606
} else {
597607
Logger::debug('Disabling samlp:Scoping for ' . var_export($idpMetadata->getString('entityid'), true));
598608
}
599609

600-
$ar->setRequesterID($requesterID);
610+
$scoping = new Scoping($proxyCount, $idpList, $requesterID);
611+
$ar->setScoping($scoping);
601612

602613
// If the downstream SP has set extensions then use them.
603614
// Otherwise use extensions that might be defined in the local SP (only makes sense in a proxy scenario)

modules/saml/src/IdP/SAML2.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Symfony\Component\HttpFoundation\{Request, Response};
2525

2626
use function array_key_exists;
27+
use function array_map;
2728
use function array_merge;
2829
use function array_unique;
2930
use function array_unshift;
@@ -419,12 +420,24 @@ public static function receiveAuthnRequest(Request $request, IdP $idp): Response
419420
$relayState = $request->getRelayState();
420421

421422
$requestId = $request->getId();
422-
$IDPList = $request->getIDPList();
423-
$ProxyCount = $request->getProxyCount();
423+
$scoping = $request->getScoping();
424+
425+
$ProxyCount = $scoping->getProxyCount();
424426
if ($ProxyCount !== null) {
425427
$ProxyCount--;
426428
}
427-
$RequesterID = $request->getRequesterID();
429+
430+
if ($scoping->getIDPList() !== null) {
431+
$IDPList = ($scoping->getIDPList()->toArray())['IDPEntry'];
432+
} else {
433+
$IDPList = [];
434+
}
435+
436+
$RequesterID = $scoping->getRequesterID();
437+
if ($RequesterID !== null) {
438+
$RequesterID = array_map('strval', $RequesterID);
439+
}
440+
428441
$forceAuthn = $request->getForceAuthn();
429442
$isPassive = $request->getIsPassive();
430443
$consumerURL = $request->getAssertionConsumerServiceURL();

tests/modules/saml/src/Auth/Source/SPTest.php

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use SimpleSAML\SAML2\Exception\Protocol\{NoAvailableIDPException, NoSupportedIDPException};
1515
use SimpleSAML\SAML2\Utils\XPath;
1616
use SimpleSAML\SAML2\XML\saml\NameID;
17+
use SimpleSAML\SAML2\XML\samlp\{IDPEntry, IDPList};
1718
use SimpleSAML\Test\Metadata\MetaDataStorageSourceTest;
1819
use SimpleSAML\TestUtils\ClearStateTestCase;
1920
use SimpleSAML\Test\Utils\{ExitTestException, SpTester};
@@ -497,12 +498,12 @@ public function testMetadataHostedBasicConfig(): void
497498
public function testSPIdpListScoping(): void
498499
{
499500
$ar = $this->createAuthnRequest([
500-
'IDPList' => ['https://scope.example.com']
501+
'IDPList' => new IDPList([new IDPEntry('https://scope.example.com')]),
501502
]);
502503

503504
$this->assertContains(
504-
'https://scope.example.com',
505-
$ar->getIDPList()
505+
(new IDPEntry('https://scope.example.com'))->toArray(),
506+
($ar->getScoping()->getIDPList()->toArray())['IDPEntry'],
506507
);
507508
}
508509

@@ -516,8 +517,8 @@ public function testIdpMetadataScoping(): void
516517
$ar = $this->createAuthnRequest([]);
517518

518519
$this->assertContains(
519-
'https://scope.example.com',
520-
$ar->getIDPList()
520+
(new IDPEntry('https://scope.example.com'))->toArray(),
521+
($ar->getScoping()->getIDPList()->toArray())['IDPEntry'],
521522
);
522523
}
523524

@@ -541,8 +542,8 @@ public function testRemoteMetadataScoping(): void
541542
} catch (ExitTestException $e) {
542543
['ar' => $ar] = $e->getTestResult();
543544
$this->assertContains(
544-
'https://scope.example.com',
545-
$ar->getIDPList()
545+
(new IDPEntry('https://scope.example.com'))->toArray(),
546+
($ar->getScoping()->getIDPList()->toArray())['IDPEntry'],
546547
);
547548
}
548549
}
@@ -555,7 +556,7 @@ public function testRemoteMetadataScoping(): void
555556
* @dataProvider getScopingOrders
556557
*/
557558
public function testSPIdpListScopingOrder(
558-
?array $stateIdpList,
559+
?IDPList $stateIdpList,
559560
?array $idpConfigArray,
560561
?array $remoteMetadata,
561562
string $expectedScope
@@ -583,8 +584,8 @@ public function testSPIdpListScopingOrder(
583584
['ar' => $ar] = $e->getTestResult();
584585

585586
$this->assertContains(
586-
$expectedScope,
587-
$ar->getIDPList()
587+
(new IDPEntry($expectedScope))->toArray(),
588+
($ar->getScoping()->getIDPList()->toArray())['IDPEntry'],
588589
);
589590
}
590591
}
@@ -593,34 +594,34 @@ public function getScopingOrders(): array
593594
{
594595
return [
595596
[
596-
'stateIdpList' => ['https//scope1.example.com'],
597-
'idpConfigArray' => ['https//scope2.example.com'],
598-
'remoteMetadata' => ['https//scope3.example.com'],
599-
'expectedScope' => 'https//scope1.example.com'
597+
'stateIdpList' => new IDPList([new IDPEntry('https://scope1.example.com')]),
598+
'idpConfigArray' => ['https://scope2.example.com'],
599+
'remoteMetadata' => ['https://scope3.example.com'],
600+
'expectedScope' => 'https://scope1.example.com'
600601
],
601602
[
602603
'stateIdpList' => null,
603-
'idpConfigArray' => ['https//scope2.example.com'],
604-
'remoteMetadata' => ['https//scope3.example.com'],
605-
'expectedScope' => 'https//scope3.example.com'
604+
'idpConfigArray' => ['https://scope2.example.com'],
605+
'remoteMetadata' => ['https://scope3.example.com'],
606+
'expectedScope' => 'https://scope3.example.com'
606607
],
607608
[
608609
'stateIdpList' => null,
609610
'idpConfigArray' => null,
610-
'remoteMetadata' => ['https//scope3.example.com'],
611-
'expectedScope' => 'https//scope3.example.com'
611+
'remoteMetadata' => ['https://scope3.example.com'],
612+
'expectedScope' => 'https://scope3.example.com'
612613
],
613614
[
614-
'stateIdpList' => ['https//scope1.example.com'],
615+
'stateIdpList' => new IDPList([new IDPEntry('https://scope1.example.com')]),
615616
'idpConfigArray' => null,
616-
'remoteMetadata' => ['https//scope3.example.com'],
617-
'expectedScope' => 'https//scope1.example.com'
617+
'remoteMetadata' => ['https://scope3.example.com'],
618+
'expectedScope' => 'https://scope1.example.com'
618619
],
619620
[
620-
'stateIdpList' => ['https//scope1.example.com'],
621-
'idpConfigArray' => ['https//scope2.example.com'],
621+
'stateIdpList' => new IDPList([new IDPEntry('https://scope1.example.com')]),
622+
'idpConfigArray' => ['https://scope2.example.com'],
622623
'remoteMetadata' => null,
623-
'expectedScope' => 'https//scope1.example.com'
624+
'expectedScope' => 'https://scope1.example.com'
624625
]
625626
];
626627
}

0 commit comments

Comments
 (0)