Loading lib/Auth/Process/SwitchAuth.php +27 −14 Original line number Diff line number Diff line Loading @@ -130,7 +130,9 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter { $this->getConfig($this->config); $mfaEnforced = Utils::isMFAEnforced($state, $this->entityID); $rpIdentifier = self::getEntityID($this->entityID, $state); $mfaEnforced = Utils::isMFAEnforced($state, $rpIdentifier); $usersCapabilities = $this->getMFAForUid($state); Loading @@ -154,13 +156,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter self::info('supported requested contexts: ' . json_encode($this->supported_requested_contexts)); $shouldPerformMFA = !$this->authnContextHelper->MFAin([ $upstreamContext, ]) && ( $mfaEnforced || empty($this->supported_requested_contexts) || $this->authnContextHelper->isMFAprefered($this->supported_requested_contexts) ); $mustPerformMFA = $this->authnContextHelper->MFAin([$upstreamContext]) ? false : ($mfaEnforced || empty($this->supported_requested_contexts)); $shouldPerformMFA = $this->authnContextHelper->MFAin([$upstreamContext]) ? false : ($mustPerformMFA || $this->authnContextHelper->isMFAprefered($this->supported_requested_contexts)); if ( $this->mfa_preferred_privacyidea_fail Loading @@ -171,10 +170,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter } if ( $shouldPerformMFA $mustPerformMFA && empty($state['Attributes'][AuthSwitcher::MFA_TOKENS]) && !empty($this->setup_mfa_redirect_url) && !in_array($this->entityID, $this->mfa_excluded_sps) && !in_array($rpIdentifier, $this->mfa_excluded_sps) ) { self::info('user must perform MFA but has no tokens, redirect to setup'); $url = Module::getModuleURL(self::SETUP_MFA_URL); Loading @@ -184,10 +183,8 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter exit; } if (empty($this->supported_requested_contexts)) { Logger::info( 'authswitcher: no requested AuthnContext can be fulfilled: ' . json_encode($requestedContexts) ); self::noAuthnContextResponder($state); Logger::info('authswitcher: no requested AuthnContext can be fulfilled'); AuthnContextHelper::noAuthnContextResponder($state); } // switch to MFA if enforced or preferred but not already done if we handle the proxy mode Loading Loading @@ -406,4 +403,20 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter $state['Attributes']['MFA_FILTER_INDEX'] = array_search($filter, $state['Attributes']['MFA_FILTERS'], true); Utils::runAuthProcFilter($filter, $this->configs[$filter], $state, $this->reserved); } private static function getEntityID($entityID, $request) { if ($entityID === null) { return $request['SPMetadata']['entityid']; } if (is_callable($entityID)) { return call_user_func($entityID, $request); } if (!is_string($entityID)) { throw new Exception( self::DEBUG_PREFIX . 'Invalid configuration option entityID. It must be a string or a callable.' ); } return $entityID; } } lib/AuthnContextHelper.php +1 −3 Original line number Diff line number Diff line Loading @@ -79,8 +79,7 @@ class AuthnContextHelper $usersCapabilities, $supportedRequestedContexts, $state['saml:RequestedAuthnContext']['Comparison'] ?? Constants::COMPARISON_EXACT, $upstreamContext, $mfaEnforced $upstreamContext ); if ($requestResult === null) { Logger::info('authswitcher: comparsion type maxium is not supported'); Loading Loading @@ -133,7 +132,6 @@ class AuthnContextHelper * @param mixed $supportedRequestedContexts * @param mixed $comparison * @param mixed|null $upstreamContext * @param mixed $mfaEnforced */ private function testComparison( $usersCapabilities, Loading lib/Utils.php +1 −19 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ class Utils } } public static function isMFAEnforced($state, $entityID = null) public static function isMFAEnforced($state, $rpIdentifier) { if (!empty($state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS])) { $settings = $state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS]; Loading @@ -73,8 +73,6 @@ class Utils $rpCategory = $state['Attributes'][AuthSwitcher::RP_CATEGORY][0] ?? 'other'; $rpIdentifier = self::getEntityID($entityID, $state); if ( !empty($settings['include_categories']) && in_array( $rpCategory, Loading @@ -92,20 +90,4 @@ class Utils Logger::info(self::DEBUG_PREFIX . 'MFA was not forced'); return false; } private static function getEntityID($entityID, $request) { if ($entityID === null) { return $request['SPMetadata']['entityid']; } if (is_callable($entityID)) { return call_user_func($entityID, $request); } if (!is_string($entityID)) { throw new Exception( self::DEBUG_PREFIX . 'Invalid configuration option entityID. It must be a string or a callable.' ); } return $entityID; } } Loading
lib/Auth/Process/SwitchAuth.php +27 −14 Original line number Diff line number Diff line Loading @@ -130,7 +130,9 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter { $this->getConfig($this->config); $mfaEnforced = Utils::isMFAEnforced($state, $this->entityID); $rpIdentifier = self::getEntityID($this->entityID, $state); $mfaEnforced = Utils::isMFAEnforced($state, $rpIdentifier); $usersCapabilities = $this->getMFAForUid($state); Loading @@ -154,13 +156,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter self::info('supported requested contexts: ' . json_encode($this->supported_requested_contexts)); $shouldPerformMFA = !$this->authnContextHelper->MFAin([ $upstreamContext, ]) && ( $mfaEnforced || empty($this->supported_requested_contexts) || $this->authnContextHelper->isMFAprefered($this->supported_requested_contexts) ); $mustPerformMFA = $this->authnContextHelper->MFAin([$upstreamContext]) ? false : ($mfaEnforced || empty($this->supported_requested_contexts)); $shouldPerformMFA = $this->authnContextHelper->MFAin([$upstreamContext]) ? false : ($mustPerformMFA || $this->authnContextHelper->isMFAprefered($this->supported_requested_contexts)); if ( $this->mfa_preferred_privacyidea_fail Loading @@ -171,10 +170,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter } if ( $shouldPerformMFA $mustPerformMFA && empty($state['Attributes'][AuthSwitcher::MFA_TOKENS]) && !empty($this->setup_mfa_redirect_url) && !in_array($this->entityID, $this->mfa_excluded_sps) && !in_array($rpIdentifier, $this->mfa_excluded_sps) ) { self::info('user must perform MFA but has no tokens, redirect to setup'); $url = Module::getModuleURL(self::SETUP_MFA_URL); Loading @@ -184,10 +183,8 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter exit; } if (empty($this->supported_requested_contexts)) { Logger::info( 'authswitcher: no requested AuthnContext can be fulfilled: ' . json_encode($requestedContexts) ); self::noAuthnContextResponder($state); Logger::info('authswitcher: no requested AuthnContext can be fulfilled'); AuthnContextHelper::noAuthnContextResponder($state); } // switch to MFA if enforced or preferred but not already done if we handle the proxy mode Loading Loading @@ -406,4 +403,20 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter $state['Attributes']['MFA_FILTER_INDEX'] = array_search($filter, $state['Attributes']['MFA_FILTERS'], true); Utils::runAuthProcFilter($filter, $this->configs[$filter], $state, $this->reserved); } private static function getEntityID($entityID, $request) { if ($entityID === null) { return $request['SPMetadata']['entityid']; } if (is_callable($entityID)) { return call_user_func($entityID, $request); } if (!is_string($entityID)) { throw new Exception( self::DEBUG_PREFIX . 'Invalid configuration option entityID. It must be a string or a callable.' ); } return $entityID; } }
lib/AuthnContextHelper.php +1 −3 Original line number Diff line number Diff line Loading @@ -79,8 +79,7 @@ class AuthnContextHelper $usersCapabilities, $supportedRequestedContexts, $state['saml:RequestedAuthnContext']['Comparison'] ?? Constants::COMPARISON_EXACT, $upstreamContext, $mfaEnforced $upstreamContext ); if ($requestResult === null) { Logger::info('authswitcher: comparsion type maxium is not supported'); Loading Loading @@ -133,7 +132,6 @@ class AuthnContextHelper * @param mixed $supportedRequestedContexts * @param mixed $comparison * @param mixed|null $upstreamContext * @param mixed $mfaEnforced */ private function testComparison( $usersCapabilities, Loading
lib/Utils.php +1 −19 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ class Utils } } public static function isMFAEnforced($state, $entityID = null) public static function isMFAEnforced($state, $rpIdentifier) { if (!empty($state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS])) { $settings = $state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS]; Loading @@ -73,8 +73,6 @@ class Utils $rpCategory = $state['Attributes'][AuthSwitcher::RP_CATEGORY][0] ?? 'other'; $rpIdentifier = self::getEntityID($entityID, $state); if ( !empty($settings['include_categories']) && in_array( $rpCategory, Loading @@ -92,20 +90,4 @@ class Utils Logger::info(self::DEBUG_PREFIX . 'MFA was not forced'); return false; } private static function getEntityID($entityID, $request) { if ($entityID === null) { return $request['SPMetadata']['entityid']; } if (is_callable($entityID)) { return call_user_func($entityID, $request); } if (!is_string($entityID)) { throw new Exception( self::DEBUG_PREFIX . 'Invalid configuration option entityID. It must be a string or a callable.' ); } return $entityID; } }