From d03139f2082610bdfd2b8f8e8e5ce2e42631fa03 Mon Sep 17 00:00:00 2001 From: Remy Blom Date: Thu, 5 Jun 2025 13:18:53 +0000 Subject: [PATCH] added support for conditional LOA --- docs/stepupsfo.md | 25 +++++++++++++++++++++++++ src/Auth/Process/SFO.php | 25 +++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/docs/stepupsfo.md b/docs/stepupsfo.md index 0bb664c..e78d990 100644 --- a/docs/stepupsfo.md +++ b/docs/stepupsfo.md @@ -96,3 +96,28 @@ running the SFO service: - The entityid and certificate configured in the authsource above. - The namespace of the subjectattribute you're using (likely something like `urn:collab:person:example.org:`). - The AssertionConsumerService location: `/module.php/stepupsfo/acs.php`. + +Conditional LOA +--------------- + +In addition to setting the `loa` setting for the authproc's config, you can also add an extra `loa` attribute to the user's attributes, for instance by adding the attribute to the LDAP or setting it using core:PHP or any other auth proc. You should of course make sure you put this auth proc before your SFO-related auth procs. + +Example: + +```php + 'authproc' => [ + 23 => [ + 'class' => 'core:PHP', + 'code' => ' + if (someCondition) { + $attributes["loa"] = "http://test.surfconext.nl/assurance/sfo-level3"; + } else { + $attributes["loa"] = "http://test.surfconext.nl/assurance/sfo-level1.5"; + } + ' + ], + ], + // other authprocs for SFO +``` + +The `loa` set in the authproc config is used as the default (optional). The `loa` set in the user's attributes will take precedence. Setting the `loa` to an empty string will skip the SFO. Not setting the `loa` will result in an error. diff --git a/src/Auth/Process/SFO.php b/src/Auth/Process/SFO.php index bcb5c86..566d0c3 100644 --- a/src/Auth/Process/SFO.php +++ b/src/Auth/Process/SFO.php @@ -17,6 +17,7 @@ use SimpleSAML\Module; use SimpleSAML\Module\saml\Message; +use function array_key_exists; use function in_array; use function sprintf; use function substr; @@ -33,6 +34,9 @@ class SFO extends Auth\ProcessingFilter /** @var \SimpleSAML\Configuration */ private Configuration $idpMetadata; + /** @var array */ + private array $config = []; + /** @var string */ private string $subjectidattribute; @@ -57,9 +61,8 @@ public function __construct(array $config, $reserved) $this->idpMetadata = $this->getIdPMetadata($config['idpEntityid']); - $config['AuthnContextClassRef'] = $config['loa']; $config['entityid'] = $config['entityID']; - $this->metadata = Configuration::loadFromArray($config); + $this->config = $config; } @@ -77,6 +80,24 @@ public function process(array &$state): void } } + if (array_key_exists('loa', $state['Attributes'])) { + // LOA is present in User's attributes + $loa = $state['Attributes']['loa']; + } else if (array_key_exists('loa', $this->config)) { + // LOA set in SFO config is default. + $loa = $this->config['loa']; + } else { + throw new Exception("SFO - No LOA set."); + } + if (empty($loa)) { + // LOA is set to an empty string, skip SFO + return; + } + Logger::info('SFO - requested LOA: ' . $loa); + + $this->config['AuthnContextClassRef'] = $loa; + $this->metadata = Configuration::loadFromArray($this->config); + $state['sfo:sp:metadata'] = $this->metadata; $state['sfo:idp:entityid'] = $this->idpMetadata->getString('entityid'); $samlstateid = Auth\State::saveState($state, 'stepupsfo:pre');