Skip to content
Snippets Groups Projects
Verified Commit d2ae9f7c authored by Pavel Břoušek's avatar Pavel Břoušek
Browse files

fix: do not show no token page when MFA is only preferred

also fix getting entityID for excluded SPs
parent aea03a82
No related branches found
No related tags found
No related merge requests found
Pipeline #279383 passed with warnings with stages
in 18 minutes and 16 seconds
...@@ -130,7 +130,9 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter ...@@ -130,7 +130,9 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter
{ {
$this->getConfig($this->config); $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); $usersCapabilities = $this->getMFAForUid($state);
...@@ -154,13 +156,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter ...@@ -154,13 +156,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter
self::info('supported requested contexts: ' . json_encode($this->supported_requested_contexts)); self::info('supported requested contexts: ' . json_encode($this->supported_requested_contexts));
$shouldPerformMFA = !$this->authnContextHelper->MFAin([ $mustPerformMFA = $this->authnContextHelper->MFAin([$upstreamContext]) ? false
$upstreamContext, : ($mfaEnforced || empty($this->supported_requested_contexts));
]) && ( $shouldPerformMFA = $this->authnContextHelper->MFAin([$upstreamContext]) ? false
$mfaEnforced : ($mustPerformMFA || $this->authnContextHelper->isMFAprefered($this->supported_requested_contexts));
|| empty($this->supported_requested_contexts)
|| $this->authnContextHelper->isMFAprefered($this->supported_requested_contexts)
);
if ( if (
$this->mfa_preferred_privacyidea_fail $this->mfa_preferred_privacyidea_fail
...@@ -171,10 +170,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter ...@@ -171,10 +170,10 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter
} }
if ( if (
$shouldPerformMFA $mustPerformMFA
&& empty($state['Attributes'][AuthSwitcher::MFA_TOKENS]) && empty($state['Attributes'][AuthSwitcher::MFA_TOKENS])
&& !empty($this->setup_mfa_redirect_url) && !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'); self::info('user must perform MFA but has no tokens, redirect to setup');
$url = Module::getModuleURL(self::SETUP_MFA_URL); $url = Module::getModuleURL(self::SETUP_MFA_URL);
...@@ -184,10 +183,8 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter ...@@ -184,10 +183,8 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter
exit; exit;
} }
if (empty($this->supported_requested_contexts)) { if (empty($this->supported_requested_contexts)) {
Logger::info( Logger::info('authswitcher: no requested AuthnContext can be fulfilled');
'authswitcher: no requested AuthnContext can be fulfilled: ' . json_encode($requestedContexts) AuthnContextHelper::noAuthnContextResponder($state);
);
self::noAuthnContextResponder($state);
} }
// switch to MFA if enforced or preferred but not already done if we handle the proxy mode // switch to MFA if enforced or preferred but not already done if we handle the proxy mode
...@@ -406,4 +403,20 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter ...@@ -406,4 +403,20 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter
$state['Attributes']['MFA_FILTER_INDEX'] = array_search($filter, $state['Attributes']['MFA_FILTERS'], true); $state['Attributes']['MFA_FILTER_INDEX'] = array_search($filter, $state['Attributes']['MFA_FILTERS'], true);
Utils::runAuthProcFilter($filter, $this->configs[$filter], $state, $this->reserved); 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;
}
} }
...@@ -79,8 +79,7 @@ class AuthnContextHelper ...@@ -79,8 +79,7 @@ class AuthnContextHelper
$usersCapabilities, $usersCapabilities,
$supportedRequestedContexts, $supportedRequestedContexts,
$state['saml:RequestedAuthnContext']['Comparison'] ?? Constants::COMPARISON_EXACT, $state['saml:RequestedAuthnContext']['Comparison'] ?? Constants::COMPARISON_EXACT,
$upstreamContext, $upstreamContext
$mfaEnforced
); );
if ($requestResult === null) { if ($requestResult === null) {
Logger::info('authswitcher: comparsion type maxium is not supported'); Logger::info('authswitcher: comparsion type maxium is not supported');
...@@ -133,7 +132,6 @@ class AuthnContextHelper ...@@ -133,7 +132,6 @@ class AuthnContextHelper
* @param mixed $supportedRequestedContexts * @param mixed $supportedRequestedContexts
* @param mixed $comparison * @param mixed $comparison
* @param mixed|null $upstreamContext * @param mixed|null $upstreamContext
* @param mixed $mfaEnforced
*/ */
private function testComparison( private function testComparison(
$usersCapabilities, $usersCapabilities,
......
...@@ -55,7 +55,7 @@ class Utils ...@@ -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])) { if (!empty($state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS])) {
$settings = $state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS]; $settings = $state['Attributes'][AuthSwitcher::MFA_ENFORCE_SETTINGS];
...@@ -73,8 +73,6 @@ class Utils ...@@ -73,8 +73,6 @@ class Utils
$rpCategory = $state['Attributes'][AuthSwitcher::RP_CATEGORY][0] ?? 'other'; $rpCategory = $state['Attributes'][AuthSwitcher::RP_CATEGORY][0] ?? 'other';
$rpIdentifier = self::getEntityID($entityID, $state);
if ( if (
!empty($settings['include_categories']) && in_array( !empty($settings['include_categories']) && in_array(
$rpCategory, $rpCategory,
...@@ -92,20 +90,4 @@ class Utils ...@@ -92,20 +90,4 @@ class Utils
Logger::info(self::DEBUG_PREFIX . 'MFA was not forced'); Logger::info(self::DEBUG_PREFIX . 'MFA was not forced');
return false; 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;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment