Skip to content
This repository was archived by the owner on Sep 19, 2022. It is now read-only.

Commit 1b52256

Browse files
author
Dominik František Bučík
authored
Updates in wayf (#150)
- property for specifying the proxy_sp_entity_id(from state) to prevent forwarding via authnContextClassRef to self - load module config only once - array property for specification of removing values from authnContextClassRef
1 parent 2de99ee commit 1b52256

File tree

3 files changed

+62
-59
lines changed

3 files changed

+62
-59
lines changed

config-templates/module_perun.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,10 @@
190190

191191
'wayf_config' => [
192192
/**
193-
* specify if disco module should filter out IdPs which are not whitelisted neither commited to CoCo or RaS.
193+
* specify if disco module should filter out IdPs which are not whitelisted neither committed to CoCo or RaS.
194194
* default is false.
195195
*/
196-
'disable_white_listing',
196+
'disable_white_listing' => false,
197197
/**
198198
* Specify translate module
199199
*/
@@ -202,7 +202,7 @@
202202
* Specify prefix for filtering AuthnContextClassRef
203203
* All AuthnContextClassRef values starts with this prefix will be removed before the request will be send to IdP
204204
*/
205-
'remove_authn_context_class_ref_prefix' => 'urn:cesnet:proxyidp:',
205+
'remove_authn_context_class_ref_prefixes' => ['urn:cesnet:proxyidp:'],
206206
/**
207207
* Add insitution configuration. The block has to specify email and url
208208
*/
@@ -212,7 +212,7 @@
212212
],
213213
/**
214214
* Warning configuration
215-
* The configuration can be loaded from file, url or directly formt his config. All possibilities has to follow
215+
* The configuration can be loaded from file, url or directly from this config. All possibilities has to follow
216216
* the structure under the "config" key.
217217
*/
218218
'warning_config' => [

lib/Disco.php

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class Disco extends PowerIdPDisco
3434
public const WAYF = 'wayf_config';
3535
# CONFIGURATION ENTRIES
3636
public const BOXED = 'boxed';
37+
public const TRANSLATE_MODULE = 'translate_module';
38+
public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES = 'remove_authn_context_class_ref_prefixes';
39+
public const DISABLE_WHITELISTING = 'disable_whitelisting';
3740
# CONFIGURATION ENTRIES IDP BLOCKS
3841
public const IDP_BLOCKS = 'idp_blocks_config';
3942
public const IDP_BLOCK_TYPE = 'type';
@@ -50,9 +53,6 @@ class Disco extends PowerIdPDisco
5053
public const ADD_INSTITUTION = 'add_institution_config';
5154
public const ADD_INSTITUTION_URL = 'url';
5255
public const ADD_INSTITUTION_EMAIL = 'email';
53-
public const TRANSLATE_MODULE = 'translate_module';
54-
public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIX = 'remove_authn_context_class_ref_prefix';
55-
public const DISABLE_WHITELISTING = 'disable_whitelisting';
5656

5757
# PARAMS AND DATA KEYS
5858
public const ENTITY_ID = "entityID";
@@ -84,12 +84,25 @@ class Disco extends PowerIdPDisco
8484
public const SAML_SP_SSO = 'saml:sp:sso';
8585

8686
private $originalsp;
87-
private array $authnContextClassRef = [];
87+
private array $originalAuthnContextClassRef = [];
88+
private $wayfConfiguration;
89+
private $perunModuleConfiguration;
90+
91+
private $proxyIdpEntityId;
8892

8993
public function __construct(
9094
array $metadataSets,
9195
$instance
9296
) {
97+
//LOAD CONFIG FOR MODULE PERUN, WHICH CONTAINS WAYF CONFIGURATION
98+
try {
99+
$this->perunModuleConfiguration = Configuration::getConfig(Disco::CONFIG_FILE_NAME);
100+
$this->wayfConfiguration = $this->perunModuleConfiguration->getConfigItem(self::WAYF);
101+
} catch (\Exception $ex) {
102+
Logger::error("perun:disco-tpl: missing or invalid '" . self::CONFIG_FILE_NAME . "' config file");
103+
throw $ex;
104+
}
105+
93106
if (!array_key_exists(self::RETURN, $_GET)) {
94107
throw new \Exception('Missing parameter: ' . self::RETURN);
95108
} else {
@@ -104,13 +117,13 @@ public function __construct(
104117

105118
if ($state !== null) {
106119
if (isset($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF])) {
107-
$this->authnContextClassRef = $state[self::SAML_REQUESTED_AUTHN_CONTEXT]
120+
$this->originalAuthnContextClassRef = $state[self::SAML_REQUESTED_AUTHN_CONTEXT]
108121
[self::AUTHN_CONTEXT_CLASS_REF];
109-
$this->removeAuthContextClassRefWithPrefix($state);
122+
$this->removeAuthContextClassRefWithPrefixes($state);
123+
if (isset($state['IdPMetadata']['entityid'])) {
124+
$this->proxyIdpEntityId = $state['IdPMetadata']['entityid'];
125+
}
110126
}
111-
112-
$id = State::saveState($state, self::SAML_SP_SSO);
113-
114127
$e = explode("=", $returnURL)[0];
115128
$newReturnURL = $e . "=" . urlencode($id);
116129
$_GET[self::RETURN] = $newReturnURL;
@@ -143,9 +156,6 @@ public function handleRequest()
143156
} else {
144157
$idpList = $this->filterList($idpList);
145158
}
146-
$preferredIdP = $this->getRecommendedIdP();
147-
$preferredIdP = array_key_exists($preferredIdP, $idpList)
148-
? $preferredIdP : null;
149159

150160
if (sizeof($idpList) === 1) {
151161
$idp = array_keys($idpList)[0];
@@ -160,15 +170,21 @@ public function handleRequest()
160170
HTTP::redirectTrustedURL($url);
161171
}
162172

173+
$preferredIdP = $this->getRecommendedIdP();
174+
$preferredIdP = array_key_exists($preferredIdP, $idpList) ? $preferredIdP : null;
175+
163176
// IF IS SET AUTHN CONTEXT CLASS REF, REDIRECT USER TO THE IDP
164-
if (isset($this->authnContextClassRef)) {
165-
if ($this->authnContextClassRef !== null) {
177+
if (isset($this->originalAuthnContextClassRef)) {
178+
if ($this->originalAuthnContextClassRef !== null) {
166179
# Check authnContextClassRef and select IdP directly if the correct value is set
167-
foreach ($this->authnContextClassRef as $value) {
180+
foreach ($this->originalAuthnContextClassRef as $value) {
168181
// VERIFY THE PREFIX IS CORRECT AND WE CAN PERFORM THE REDIRECT
169182
$acrStartSubstr = substr($value, 0, strlen(Disco::URN_CESNET_PROXYIDP_IDPENTITYID));
170183
if ($acrStartSubstr === Disco::URN_CESNET_PROXYIDP_IDPENTITYID) {
171184
$idpEntityId = substr($value, strlen(Disco::URN_CESNET_PROXYIDP_IDPENTITYID), strlen($value));
185+
if ($idpEntityId === $this->proxyIdpEntityId) {
186+
continue;
187+
}
172188
Logger::info('Redirecting to ' . $idpEntityId);
173189
$url = Disco::buildContinueUrl(
174190
$this->spEntityId,
@@ -182,15 +198,6 @@ public function handleRequest()
182198
}
183199
}
184200

185-
//LOAD CONFIG FOR MODULE PERUN, WHICH CONTAINS WAYF CONFIGURATION
186-
$perunModuleConfig = null;
187-
try {
188-
$perunModuleConfig = Configuration::getConfig(Disco::CONFIG_FILE_NAME);
189-
} catch (\Exception $ex) {
190-
Logger::error("perun:disco-tpl: missing or invalid '" . self::CONFIG_FILE_NAME . "' config file");
191-
throw $ex;
192-
}
193-
194201
$warningAttributes = null;
195202
try {
196203
$warningInstance = WarningConfiguration::getInstance();
@@ -206,9 +213,9 @@ public function handleRequest()
206213
$t->data[self::ENTITY_ID] = $this->spEntityId;
207214
$t->data[self::RETURN] = $this->returnURL;
208215
$t->data[self::RETURN_ID_PARAM] = $this->returnIdParam;
209-
$t->data[self::AUTHN_CONTEXT_CLASS_REF] = $this->authnContextClassRef;
216+
$t->data[self::AUTHN_CONTEXT_CLASS_REF] = $this->originalAuthnContextClassRef;
210217
$t->data[self::WARNING_ATTRIBUTES] = $warningAttributes;
211-
$t->data[self::WAYF] = $perunModuleConfig->getConfigItem(self::WAYF);
218+
$t->data[self::WAYF] = $this->wayfConfiguration;
212219
$t->show();
213220
}
214221

@@ -221,8 +228,7 @@ public function handleRequest()
221228
*/
222229
protected function filterList($list): array
223230
{
224-
$conf = Configuration::getConfig(self::CONFIG_FILE_NAME);
225-
$disableWhitelisting = $conf->getBoolean(self::DISABLE_WHITELISTING, false);
231+
$disableWhitelisting = $this->wayfConfiguration->getBoolean(self::DISABLE_WHITELISTING, false);
226232

227233
if (!isset($this->originalsp[Disco::METADATA_DO_NOT_FILTER_IDPS])
228234
|| !$this->originalsp[Disco::METADATA_DO_NOT_FILTER_IDPS]
@@ -441,24 +447,24 @@ public static function buildContinueUrlWithoutIdPEntityId(
441447
* @param $state
442448
* @throws \Exception
443449
*/
444-
public function removeAuthContextClassRefWithPrefix(&$state)
450+
public function removeAuthContextClassRefWithPrefixes(&$state)
445451
{
446-
$conf = Configuration::getConfig(self::CONFIG_FILE_NAME);
447-
$prefix = $conf->getString(self::REMOVE_AUTHN_CONTEXT_CLASS_PREFIX, null);
452+
$prefixes = $this->wayfConfiguration->getArray(self::REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES, []);
448453

449-
if ($prefix === null) {
454+
if (empty($prefixes)) {
450455
return;
451456
}
452457
unset($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF]);
453-
$array = [];
454-
foreach ($this->authnContextClassRef as $value) {
455-
if (!(substr($value, 0, strlen($prefix)) === $prefix)) {
456-
array_push($array, $value);
458+
$filteredAcrs = [];
459+
foreach ($this->originalAuthnContextClassRef as $acr) {
460+
foreach ($prefixes as $prefix) {
461+
if (!(substr($acr, 0, strlen($prefix)) === $prefix)) {
462+
array_push($filteredAcrs, $acr);
463+
}
457464
}
458465
}
459-
if (!empty($array)) {
460-
$state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF]
461-
= $array;
466+
if (!empty($filteredAcrs)) {
467+
$state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF] = $filteredAcrs;
462468
}
463469
}
464470

themes/perun/perun/disco-tpl.php

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,24 @@
2121
$this->data['head'] .= '<link rel="stylesheet" media="screen" type="text/css" href="' .
2222
Module::getModuleUrl('perun/res/css/disco.css') . '" />';
2323

24-
$authContextClassRef = null;
25-
$idpEntityId = null;
26-
2724
$wayfConfig = $this->data[Disco::WAYF];
2825

2926
$translateModule = $wayfConfig->getString(Disco::TRANSLATE_MODULE, 'disco');
30-
3127
$addInstitutionConfig = $wayfConfig->getConfigItem(Disco::ADD_INSTITUTION, null);
3228

3329
$warningAttributes = $this->data[Disco::WARNING_ATTRIBUTES];
34-
$this->includeInlineTranslation('{perun:disco:warning_title}', $warningAttributes->getTitle());
35-
$this->includeInlineTranslation('{perun:disco:warning_text}', $warningAttributes->getText());
36-
37-
// IF WARNING ERROR IS ENABLED, DISPLAY IT AND STOP THE USER
38-
if ($warningAttributes->isEnabled() && $warningAttributes->getType() === WarningConfiguration::WARNING_TYPE_ERROR) {
39-
$this->data['header'] = $this->t('{perun:disco:warning}');
40-
$this->includeAtTemplateBase('includes/header.php');
41-
echo Disco::showWarning($this, $warningAttributes);
42-
$this->includeAtTemplateBase('includes/footer.php');
43-
echo Disco::getScripts($wayfConfig->getBoolean(Disco::BOXED, false)) . PHP_EOL;
44-
exit;
30+
if ($warningAttributes !== null) {
31+
$this->includeInlineTranslation('{perun:disco:warning_title}', $warningAttributes->getTitle());
32+
$this->includeInlineTranslation('{perun:disco:warning_text}', $warningAttributes->getText());
33+
// IF WARNING ERROR IS ENABLED, DISPLAY IT AND STOP THE USER
34+
if ($warningAttributes->isEnabled() && $warningAttributes->getType() === WarningConfiguration::WARNING_TYPE_ERROR) {
35+
$this->data['header'] = $this->t('{perun:disco:warning}');
36+
$this->includeAtTemplateBase('includes/header.php');
37+
echo Disco::showWarning($this, $warningAttributes);
38+
$this->includeAtTemplateBase('includes/footer.php');
39+
echo Disco::getScripts($wayfConfig->getBoolean(Disco::BOXED, false)) . PHP_EOL;
40+
exit;
41+
}
4542
}
4643

4744
// START DISPLAYING REGULAR WAYF (for users or add-institution)
@@ -56,7 +53,7 @@
5653
$this->includeAtTemplateBase('includes/header.php');
5754

5855
# IF WE HAVE A WARNING, DISPLAY IT TO THE USER
59-
if ($warningAttributes->isEnabled()) {
56+
if ($warningAttributes !== null && $warningAttributes->isEnabled()) {
6057
echo Disco::showWarning($this, $warningAttributes);
6158
}
6259
###

0 commit comments

Comments
 (0)