Skip to content

Commit a876638

Browse files
ghalsetvdijen
andcommitted
Handle AuthnContextClassRef changes when proxying (#1874)
* Fix for when no RequestedAuthnContext is provided PHP Warning: Trying to access array offset on value of type null * Handle AuthnContextClassRef changes when proxying * Perform strict comparisons --------- Co-authored-by: Tim van Dijen <tvdijen@gmail.com>
1 parent 72ad891 commit a876638

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

docs/simplesamlphp-changelog.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ Released 2023-10-30
5656
* Update vulnerable composer (CVE-2023-43655; not affected)
5757
* Fixed a potential XSS-through-DOM (3x; not affected)
5858
* Fixed a warning in the RequestedAuthnContextSelector
59-
* Fixed file logging handler to not fail on the first write after file-creation (#1877)
6059

6160
## Version 2.0.6
6261

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,30 @@ public function reauthenticate(array &$state): void
886886
$response = self::askForIdPChange($state);
887887
$response->send();
888888
}
889+
890+
/*
891+
* When proxying AuthnContextClassRef, we also need to check if the
892+
* original IdP used a compatible AuthnContext. If not, we may need
893+
* need to do step-up authentication (e.g. for requesting MFA). At
894+
* the moment this only handles exact comparisons, since handling
895+
* better/minimum/maximum would require a prioritised list.
896+
*/
897+
if (
898+
$this->passAuthnContextClassRef
899+
&& isset($state['saml:RequestedAuthnContext'])
900+
&& $state['saml:RequestedAuthnContext']['Comparison'] === Constants::COMPARISON_EXACT
901+
&& isset($data['saml:sp:AuthnContext'])
902+
&& $state['saml:RequestedAuthnContext']['AuthnContextClassRef'][0] !== $data['saml:sp:AuthnContext']
903+
) {
904+
Logger::warning(sprintf(
905+
"Reauthentication requires change in AuthnContext from '%s' to '%s'.",
906+
$data['saml:sp:AuthnContext'],
907+
$state['saml:RequestedAuthnContext']['AuthnContextClassRef'][0]
908+
));
909+
$state['saml:idp'] = $data['saml:sp:IdP'];
910+
$state['saml:sp:AuthId'] = $this->authId;
911+
self::tryStepUpAuth($state);
912+
}
889913
}
890914

891915

@@ -931,6 +955,37 @@ public static function askForIdPChange(array &$state): RedirectResponse
931955
}
932956

933957

958+
/**
959+
* Attempt to re-authenticate using the same identity provider, perhaps
960+
* with different requirements (e.g. AuthnContext). Note that this method
961+
* is intended for instances of SimpleSAMLphp running as a SAML proxy,
962+
* and therefore acting as both an SP and an IdP at the same time.
963+
*
964+
* @param array The state array
965+
* The following keys must be defined:
966+
* - 'saml:idp': the IdP to re-authenticate with
967+
* - 'saml:sp:AuthId': the identifier of the current authentication source.
968+
* @throws \SAML2\Exception\Protocol\NoPassiveException In case the authentication request was passive.
969+
*/
970+
public static function tryStepUpAuth(array &$state): void
971+
{
972+
Assert::keyExists($state, 'saml:idp');
973+
Assert::keyExists($state, 'saml:sp:AuthId');
974+
975+
if (isset($state['isPassive']) && (bool) $state['isPassive']) {
976+
// passive request, we cannot authenticate the user
977+
throw new NoPassiveException(
978+
Constants::STATUS_REQUESTER . ': Reauthentication required'
979+
);
980+
}
981+
982+
/** @var \SimpleSAML\Module\saml\Auth\Source\SP $as */
983+
$as = new Auth\Simple($state['saml:sp:AuthId']);
984+
$as->login($state);
985+
Assert::true(false);
986+
}
987+
988+
934989
/**
935990
* Log the user out before logging in again.
936991
*

0 commit comments

Comments
 (0)