Skip to content
Snippets Groups Projects
Unverified Commit 04eb5e48 authored by Pavel Břoušek's avatar Pavel Břoušek Committed by GitHub
Browse files

Merge pull request #31 from CESNET/realm

Improvements for problematic situations
parents b4d04d9b f52389be
Branches
Tags
No related merge requests found
...@@ -38,6 +38,7 @@ Use this filter to read user mfa tokens from PrivacyIDEA server to state attribu ...@@ -38,6 +38,7 @@ Use this filter to read user mfa tokens from PrivacyIDEA server to state attribu
'tokens_Attr' => 'privacyIDEATokens', 'tokens_Attr' => 'privacyIDEATokens',
'privacy_idea_username' => 'admin', 'privacy_idea_username' => 'admin',
'privacy_idea_passwd' => 'secret', 'privacy_idea_passwd' => 'secret',
//'privacy_idea_realm' => 'superadminrealm', // optional
'privacy_idea_domain' => 'https://mfa.id.muni.cz', 'privacy_idea_domain' => 'https://mfa.id.muni.cz',
'tokens_type' => [ 'tokens_type' => [
'TOTP', 'TOTP',
...@@ -45,6 +46,8 @@ Use this filter to read user mfa tokens from PrivacyIDEA server to state attribu ...@@ -45,6 +46,8 @@ Use this filter to read user mfa tokens from PrivacyIDEA server to state attribu
], ],
'user_attribute' => 'eduPersonPrincipalName', 'user_attribute' => 'eduPersonPrincipalName',
'token_type_attr' => 'type', 'token_type_attr' => 'type',
//'connect_timeout' => 10, // optional, connect timeout in seconds
//'timeout' => 10, // optional, timeout in seconds
], ],
], ],
``` ```
......
...@@ -16,12 +16,18 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter ...@@ -16,12 +16,18 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter
private const AS_PI_AUTH_TOKEN = 'auth_token'; private const AS_PI_AUTH_TOKEN = 'auth_token';
private const AS_PI_AUTH_TOKEN_ISSUED_AT = 'auth_token_issued_at'; private const AS_PI_AUTH_TOKEN_ISSUED_AT = 'auth_token_issued_at';
private $connect_timeout = 0;
private $timeout;
private $tokens_attr = 'mfaTokens'; private $tokens_attr = 'mfaTokens';
private $privacy_idea_username; private $privacy_idea_username;
private $privacy_idea_passwd; private $privacy_idea_passwd;
private $privacy_idea_realm;
private $privacy_idea_domain; private $privacy_idea_domain;
private $tokens_type = ['TOTP', 'WebAuthn']; private $tokens_type = ['TOTP', 'WebAuthn'];
...@@ -39,9 +45,12 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter ...@@ -39,9 +45,12 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter
parent::__construct($config, $reserved); parent::__construct($config, $reserved);
$config = Configuration::loadFromArray($config['config']); $config = Configuration::loadFromArray($config['config']);
$this->connect_timeout = $config->getInteger('connect_timeout', $this->connect_timeout);
$this->timeout = $config->getInteger('timeout', $this->timeout);
$this->tokens_attr = $config->getString('tokens_Attr', $this->tokens_attr); $this->tokens_attr = $config->getString('tokens_Attr', $this->tokens_attr);
$this->privacy_idea_username = $config->getString('privacy_idea_username'); $this->privacy_idea_username = $config->getString('privacy_idea_username');
$this->privacy_idea_passwd = $config->getString('privacy_idea_passwd'); $this->privacy_idea_passwd = $config->getString('privacy_idea_passwd');
$this->privacy_idea_realm = $config->getString('privacy_idea_realm', null);
$this->privacy_idea_domain = $config->getString('privacy_idea_domain'); $this->privacy_idea_domain = $config->getString('privacy_idea_domain');
$this->tokens_type = $config->getArray('tokens_type', $this->tokens_type); $this->tokens_type = $config->getArray('tokens_type', $this->tokens_type);
$this->user_attribute = $config->getString('user_attribute', $this->user_attribute); $this->user_attribute = $config->getString('user_attribute', $this->user_attribute);
...@@ -58,7 +67,7 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter ...@@ -58,7 +67,7 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter
$state[Authswitcher::PRIVACY_IDEA_FAIL] = false; $state[Authswitcher::PRIVACY_IDEA_FAIL] = false;
$state['Attributes'][$this->tokens_attr] = []; $state['Attributes'][$this->tokens_attr] = [];
$admin_token = $this->getAdminToken(); $admin_token = $this->getAdminToken();
if (null === $admin_token) { if (empty($admin_token)) {
$state[AuthSwitcher::PRIVACY_IDEA_FAIL] = true; $state[AuthSwitcher::PRIVACY_IDEA_FAIL] = true;
return; return;
...@@ -98,8 +107,15 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter ...@@ -98,8 +107,15 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter
'username' => $this->privacy_idea_username, 'username' => $this->privacy_idea_username,
'password' => $this->privacy_idea_passwd, 'password' => $this->privacy_idea_passwd,
]; ];
if (null !== $this->privacy_idea_realm) {
$data['realm'] = $this->privacy_idea_realm;
}
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connect_timeout);
if (null !== $this->timeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
}
curl_setopt($ch, CURLOPT_URL, $this->privacy_idea_domain . '/auth'); curl_setopt($ch, CURLOPT_URL, $this->privacy_idea_domain . '/auth');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$paramsJson = json_encode($data); $paramsJson = json_encode($data);
...@@ -118,9 +134,13 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter ...@@ -118,9 +134,13 @@ class GetMfaTokensPrivacyIDEA extends \SimpleSAML\Auth\ProcessingFilter
return $response['result']['value']['token']; return $response['result']['value']['token'];
} }
private function getPrivacyIdeaTokensByType($state, $type, $admin_token) private function getPrivacyIdeaTokensByType(&$state, $type, $admin_token)
{ {
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connect_timeout);
if (null !== $this->timeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
}
curl_setopt($ch, CURLOPT_URL, $this->privacy_idea_domain . '/token/?user=' . curl_setopt($ch, CURLOPT_URL, $this->privacy_idea_domain . '/token/?user=' .
$state['Attributes'][$this->user_attribute][0] . '&active=True&type=' . $type); $state['Attributes'][$this->user_attribute][0] . '&active=True&type=' . $type);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
......
...@@ -122,22 +122,19 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter ...@@ -122,22 +122,19 @@ class SwitchAuth extends \SimpleSAML\Auth\ProcessingFilter
self::info('supported requested contexts: ' . json_encode($state[AuthSwitcher::SUPPORTED_REQUESTED_CONTEXTS])); self::info('supported requested contexts: ' . json_encode($state[AuthSwitcher::SUPPORTED_REQUESTED_CONTEXTS]));
if ( $shouldPerformMFA = !AuthnContextHelper::MFAin([
$this->mfa_preferred_privacyidea_fail && isset($state[AuthSwitcher::PRIVACY_IDEA_FAIL]) &&
$state[AuthSwitcher::PRIVACY_IDEA_FAIL] &&
AuthnContextHelper::isMFAprefered($state[Authswitcher::SUPPORTED_REQUESTED_CONTEXTS]) &&
!AuthnContextHelper::MFAin([$upstreamContext])
) {
throw new Exception(self::DEBUG_PREFIX . 'MFA is preferred but connection to privacyidea failed.');
}
// switch to MFA if enforced or preferred but not already done if we handle the proxy mode
$performMFA = AuthnContextHelper::MFAin($usersCapabilities) && !AuthnContextHelper::MFAin([
$upstreamContext, $upstreamContext,
]) && ($this->mfa_enforced || AuthnContextHelper::isMFAprefered( ]) && ($this->mfa_enforced || AuthnContextHelper::isMFAprefered(
$state[AuthSwitcher::SUPPORTED_REQUESTED_CONTEXTS] $state[AuthSwitcher::SUPPORTED_REQUESTED_CONTEXTS]
)); ));
if ($this->mfa_preferred_privacyidea_fail && !empty($state[AuthSwitcher::PRIVACY_IDEA_FAIL]) && $shouldPerformMFA) {
throw new Exception(self::DEBUG_PREFIX . 'MFA should be performed but connection to privacyidea failed.');
}
// switch to MFA if enforced or preferred but not already done if we handle the proxy mode
$performMFA = AuthnContextHelper::MFAin($usersCapabilities) && $shouldPerformMFA;
$maxUserCapability = ''; $maxUserCapability = '';
if (in_array(AuthSwitcher::MFA, $usersCapabilities, true)) { if (in_array(AuthSwitcher::MFA, $usersCapabilities, true)) {
$maxUserCapability = AuthSwitcher::MFA; $maxUserCapability = AuthSwitcher::MFA;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment