Skip to content
Snippets Groups Projects
Verified Commit 5b818335 authored by Dominik František Bučík's avatar Dominik František Bučík
Browse files

fix: :bug: Fix processing nagios IDP hints via ACRs

parent 759e2468
No related branches found
No related tags found
1 merge request!40fix: 🐛 Fix processing nagios IDP hints via ACRs
Pipeline #221190 passed
...@@ -4,10 +4,12 @@ declare(strict_types=1); ...@@ -4,10 +4,12 @@ declare(strict_types=1);
namespace SimpleSAML\Module\elixir; namespace SimpleSAML\Module\elixir;
use SimpleSAML\Auth\State;
use SimpleSAML\Configuration; use SimpleSAML\Configuration;
use SimpleSAML\Logger; use SimpleSAML\Logger;
use SimpleSAML\Module\discopower\PowerIdPDisco; use SimpleSAML\Module\discopower\PowerIdPDisco;
use SimpleSAML\Module\elixir\discowarning\WarningConfiguration; use SimpleSAML\Module\elixir\discowarning\WarningConfiguration;
use SimpleSAML\Utils\HTTP;
/** /**
* This class implements a IdP discovery service. * This class implements a IdP discovery service.
...@@ -24,13 +26,32 @@ class Disco extends PowerIdPDisco ...@@ -24,13 +26,32 @@ class Disco extends PowerIdPDisco
public const CONFIG_FILE_NAME = 'module_elixir.php'; public const CONFIG_FILE_NAME = 'module_elixir.php';
public const URN_CESNET_PROXYIDP_IDPENTITYID = 'urn:cesnet:proxyidp:idpentityid:';
public const INTERFACE = 'interface';
public const RPC = 'rpc';
public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES = 'remove_authn_context_class_ref_prefixes';
public const RETURN = 'return';
public const AUTH_ID = 'AuthID'; public const AUTH_ID = 'AuthID';
public const CONTINUE_URL = 'continueUrl';
// STATE KEYS
public const SAML_REQUESTED_AUTHN_CONTEXT = 'saml:RequestedAuthnContext';
public const STATE_AUTHN_CONTEXT_CLASS_REF = 'AuthnContextClassRef';
public const SAML_SP_SSO = 'saml:sp:sso'; public const SAML_SP_SSO = 'saml:sp:sso';
public const WARNING = 'warningAttributes'; public const AUTHN_CONTEXT_CLASS_REF = 'AuthnContextClassRef';
public const CONTINUE_URL = 'continueUrl'; public const NAME = 'name';
public const WARNING = 'warningAttributes';
// ROOT CONFIGURATION ENTRY // ROOT CONFIGURATION ENTRY
...@@ -40,6 +61,8 @@ class Disco extends PowerIdPDisco ...@@ -40,6 +61,8 @@ class Disco extends PowerIdPDisco
// VARIABLES // VARIABLES
private array $originalAuthnContextClassRef = [];
private $discoConfiguration; private $discoConfiguration;
private $upstreamIdpEntityId; private $upstreamIdpEntityId;
...@@ -61,6 +84,26 @@ class Disco extends PowerIdPDisco ...@@ -61,6 +84,26 @@ class Disco extends PowerIdPDisco
throw $ex; throw $ex;
} }
if (!array_key_exists(self::RETURN, $_GET)) {
throw new \Exception('Missing parameter: ' . self::RETURN);
}
$returnURL = HTTP::checkURLAllowed($_GET[self::RETURN]);
parse_str(parse_url($returnURL)['query'], $query);
if (isset($query[self::AUTH_ID])) {
$id = explode(':', $query[self::AUTH_ID])[0];
$state = State::loadState($id, self::SAML_SP_SSO, true);
if (null !== $state) {
if (!empty($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF])) {
$this->originalAuthnContextClassRef =
$state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF];
$this->removeAuthContextClassRefWithPrefixes($state);
State::saveState($state, self::SAML_SP_SSO);
}
}
}
$this->upstreamIdpEntityId = $this->discoConfiguration->getString(self::UPSTREAM_IDP_ENTITY_ID, ''); $this->upstreamIdpEntityId = $this->discoConfiguration->getString(self::UPSTREAM_IDP_ENTITY_ID, '');
if (empty($this->upstreamIdpEntityId)) { if (empty($this->upstreamIdpEntityId)) {
Logger::error( Logger::error(
...@@ -79,6 +122,27 @@ class Disco extends PowerIdPDisco ...@@ -79,6 +122,27 @@ class Disco extends PowerIdPDisco
{ {
$this->start(); $this->start();
// IF IS SET AUTHN CONTEXT CLASS REF, REDIRECT USER TO THE IDP
if (!empty($this->originalAuthnContextClassRef)) {
// Check authnContextClassRef and select IdP directly if the correct value is set
foreach ($this->originalAuthnContextClassRef as $value) {
// VERIFY THE PREFIX IS CORRECT AND WE CAN PERFORM THE REDIRECT
$acrStartSubstr = substr($value, 0, strlen(self::URN_CESNET_PROXYIDP_IDPENTITYID));
if (self::URN_CESNET_PROXYIDP_IDPENTITYID === $acrStartSubstr) {
$idpEntityId = substr($value, strlen(self::URN_CESNET_PROXYIDP_IDPENTITYID), strlen($value));
Logger::info('Redirecting to ' . $idpEntityId);
$continueUrl = self::buildContinueUrl(
$this->spEntityId,
$this->returnURL,
$this->returnIdParam,
$idpEntityId
);
HTTP::redirectTrustedURL($continueUrl);
exit;
}
}
}
$continueUrl = self::buildContinueUrl( $continueUrl = self::buildContinueUrl(
$this->spEntityId, $this->spEntityId,
$this->returnURL, $this->returnURL,
...@@ -104,4 +168,36 @@ class Disco extends PowerIdPDisco ...@@ -104,4 +168,36 @@ class Disco extends PowerIdPDisco
'returnIDParam=' . urlencode($returnIDParam) . '&' . 'returnIDParam=' . urlencode($returnIDParam) . '&' .
'idpentityid=' . urlencode($idpEntityId); 'idpentityid=' . urlencode($idpEntityId);
} }
/**
* This method remove all AuthnContextClassRef which start with prefix from configuration.
*
* @param mixed $state
*/
public function removeAuthContextClassRefWithPrefixes(&$state)
{
$prefixes = $this->discoConfiguration->getArray(self::REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES, []);
if (empty($prefixes)) {
return;
}
unset($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF]);
$filteredAcrs = [];
foreach ($this->originalAuthnContextClassRef as $acr) {
$acr = trim($acr);
$retain = true;
foreach ($prefixes as $prefix) {
if (substr($acr, 0, strlen($prefix)) === $prefix) {
$retain = false;
break;
}
}
if ($retain) {
$filteredAcrs[] = $acr;
}
}
if (!empty($filteredAcrs)) {
$state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF] = $filteredAcrs;
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment