diff --git a/attributealter/feideaccess.php b/attributealter/feideaccess.php new file mode 100644 index 0000000000000000000000000000000000000000..92132294e16b37fa0f7c4ad92ba4dd037d3d2f7a --- /dev/null +++ b/attributealter/feideaccess.php @@ -0,0 +1,32 @@ +<?php +function attributealter_feideaccess(&$attributes, $spEntityId = null, $idpEntityId = null) { + assert('$spEntityId !== NULL'); + assert('$idpEntityId !== NULL'); + + $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); + $spMetadata = $metadata->getMetadata($spEntityId, 'saml20-sp-remote'); + if(!array_key_exists('feide.allowedorgs', $spMetadata)) { + SimpleSAML_Logger::info('FEIDE access control: No limits set for SP: ' . $spEntityId); + return; + } + $allowedOrgs = $spMetadata['feide.allowedorgs']; + + if(!array_key_exists('eduPersonPrincipalName', $attributes)) { + throw new Exception('FEIDE access control requires the eduPersonPrincipalName to be present.'); + } + + $eppn = $attributes['eduPersonPrincipalName'][0]; + $org = explode('@', $eppn); + $org = $org[1]; + + if(!in_array($org, $allowedOrgs, TRUE)) { + $session = SimpleSAML_Session::getInstance(); + SimpleSAML_Logger::error('FEIDE access control: Organization "' . $org . + '" not in list of allowed organization for SP "' . $spEntityId . '".'); + SimpleSAML_Utilities::fatalError($session->getTrackId(), 'NOACCESS'); + } + + SimpleSAML_Logger::info('FEIDE access control: Organization "' . $org . + '" is allowed for SP "' . $spEntityId . '".'); +} +?> \ No newline at end of file diff --git a/templates/default/login-feide.php b/templates/default/login-feide.php index 9f301a80c9ae7c895e7785a53771e23ccdfca919..6d71242bfd16c566cfae8af6bb1360e9c3000d6b 100644 --- a/templates/default/login-feide.php +++ b/templates/default/login-feide.php @@ -19,7 +19,8 @@ $this->includeAtTemplateBase('includes/header.php'); <legend>Choose your home organization</legend> <select name="org" tabindex="1"> <?php - foreach ($this->data['ldapconfig'] AS $key => $entry) { + foreach ($this->data['allowedorgs'] AS $key) { + $entry = $this->data['ldapconfig'][$key]; echo '<option ' . ($key == $this->data['org'] ? 'selected="selected" ' : '') . 'value="' . htmlspecialchars($key) . '">' . htmlspecialchars($entry['description']) . '</option>'; diff --git a/www/auth/login-feide.php b/www/auth/login-feide.php index b5bf2c304de9167422c0a6c03211c8348f5b82a9..739fbd274d8720338caacccfac3625586602fcdf 100644 --- a/www/auth/login-feide.php +++ b/www/auth/login-feide.php @@ -63,6 +63,16 @@ try { $spentityid = $authrequestcache['Issuer']; $spmetadata = $metadata->getMetadata($spentityid, 'saml20-sp-remote'); +/* + * Find the list of allowed organizations. + */ +$allowedOrgs = array_keys($ldaporgconfig); +if(array_key_exists('feide.allowedorgs', $spmetadata)) { + assert('is_array($spmetadata["feide.allowedorgs"])'); + $allowedOrgs = array_intersect($spmetadata['feide.allowedorgs'], $allowedOrgs); +} + + $error = null; $attributes = array(); @@ -95,7 +105,12 @@ if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'change_org') { $selectorg = true; } - +/* + * The user may have previously selected an organization which the SP doesn't allow. Correct this. + */ +if ($selectorg === FALSE && !in_array($org, $allowedOrgs, TRUE)) { + $selectorg = TRUE; +} if (isset($_REQUEST['username'])) { @@ -260,13 +275,31 @@ $t->data['relaystate'] = $_REQUEST['RelayState']; $t->data['ldapconfig'] = $ldaporgconfig; $t->data['protocol'] = $protocol; $t->data['authid'] = $authid; -$t->data['splogo'] = $spmetadata['logo']; -$t->data['spdesc'] = $spmetadata['description']; -$t->data['spname'] = $spmetadata['name']; -$t->data['contact'] = $spmetadata['contact']; + +if(array_key_exists('logo', $spmetadata)) { + $t->data['splogo'] = $spmetadata['logo']; +} else { + $t->data['splogo'] = NULL; +} +if(array_key_exists('description', $spmetadata)) { + $t->data['spdesc'] = $spmetadata['description']; +} else { + $t->data['spdesc'] = NULL; +} +if(array_key_exists('name', $spmetadata)) { + $t->data['spname'] = $spmetadata['name']; +} else { + $t->data['spname'] = NULL; +} +if(array_key_exists('contact', $spmetadata)) { + $t->data['contact'] = $spmetadata['contact']; +} else { + $t->data['contact'] = NULL; +} $t->data['selectorg'] = $selectorg; $t->data['org'] = $org; +$t->data['allowedorgs'] = $allowedOrgs; $t->data['error'] = $error; if (isset($error)) { $t->data['username'] = $_POST['username'];