From d3a8964bc428e315f789e352be94f7fc8581c401 Mon Sep 17 00:00:00 2001 From: Lars Mikal Rogne Date: Mon, 20 Nov 2023 13:47:25 +0100 Subject: [PATCH 1/2] Support selection of protocol binding for individual IdP's. --- classes/admin/setting_idpmetadata.php | 1 + classes/form/availableidps.php | 6 ++++ classes/protocol_binding.php | 49 +++++++++++++++++++++++++++ config/authsources.php | 3 ++ db/install.xml | 1 + db/upgrade.php | 12 +++++++ lang/en/auth_saml2.php | 2 ++ version.php | 4 +-- 8 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 classes/protocol_binding.php diff --git a/classes/admin/setting_idpmetadata.php b/classes/admin/setting_idpmetadata.php index d82602206..2efc17bc4 100644 --- a/classes/admin/setting_idpmetadata.php +++ b/classes/admin/setting_idpmetadata.php @@ -177,6 +177,7 @@ private function process_idp_xml(idp_data $idp, DOMElement $idpelements, DOMXPat $newidp->adminidp = 0; $newidp->defaultname = $idpname; $newidp->logo = $logo; + $newidp->protocolbinding = 0; $DB->insert_record('auth_saml2_idps', $newidp); } diff --git a/classes/form/availableidps.php b/classes/form/availableidps.php index 0639da3b9..f2090761d 100644 --- a/classes/form/availableidps.php +++ b/classes/form/availableidps.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die(); +use auth_saml2\protocol_binding; use moodleform; use core\output\notification; @@ -92,6 +93,11 @@ public function definition() { $mform->addHelpButton($fieldkey.'[whitelist]', 'multiidp:label:whitelist', 'auth_saml2'); $mform->setType($fieldkey.'[whitelist]', PARAM_TEXT); + $select = $mform->addElement('select', $fieldkey.'[protocolbinding]', + get_string('multiidp:label:protocolbinding', 'auth_saml2'), protocol_binding::form_options()); + $select->setSelected($idpentity['protocolbinding']); + $mform->addHelpButton($fieldkey.'[protocolbinding]', 'multiidp:label:protocolbinding', 'auth_saml2'); + // Moodle Workplace - Tenant availability edit button. if (class_exists('\tool_tenant\local\auth\saml2\manager')) { $links = component_class_callback('\tool_tenant\local\auth\saml2\manager', diff --git a/classes/protocol_binding.php b/classes/protocol_binding.php new file mode 100644 index 000000000..b21cf82f0 --- /dev/null +++ b/classes/protocol_binding.php @@ -0,0 +1,49 @@ + 'HTTP Post', + self::HTTP_ARTIFACT => 'HTTP Artifact', + self::HOK_SSO => 'Holder-of-Key Web Browser SSO', + self::HTTP_REDIRECT => 'HTTP Redirect', + ]; + } +} diff --git a/config/authsources.php b/config/authsources.php index b1acd3145..4fb43c9d2 100644 --- a/config/authsources.php +++ b/config/authsources.php @@ -34,9 +34,11 @@ if (!empty($SESSION->saml2idp) && array_key_exists($SESSION->saml2idp, $saml2auth->metadataentities)) { $idpentityid = $saml2auth->metadataentities[$SESSION->saml2idp]->entityid; + $protocolbinding = $saml2auth->metadataentities[$SESSION->saml2idp]->protocolbinding; } else { // Case for specifying no $SESSION IdP, select the first configured IdP as the default. $idpentityid = reset($saml2auth->metadataentities)->entityid; + $protocolbinding = reset($saml2auth->metadataentities)->protocolbinding; } $defaultspentityid = "$baseurl/auth/saml2/sp/metadata.php"; @@ -86,6 +88,7 @@ ], 'attributes' => $attributes, 'attributes.required' => $attributesrequired, + 'ProtocolBinding' => \auth_saml2\protocol_binding::get_binding($protocolbinding), ]; if (!empty($saml2auth->config->assertionsconsumerservices)) { diff --git a/db/install.xml b/db/install.xml index 48b89fdde..349a8a3a0 100644 --- a/db/install.xml +++ b/db/install.xml @@ -32,6 +32,7 @@ + diff --git a/db/upgrade.php b/db/upgrade.php index f64dc6e8c..d908d73dc 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -410,5 +410,17 @@ function xmldb_auth_saml2_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2023100300, 'auth', 'saml2'); } + if ($oldversion < 2023112000) { + + $table = new xmldb_table('auth_saml2_idps'); + $field = new xmldb_field('protocolbinding', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'whitelist'); + + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + upgrade_plugin_savepoint(true, 2023112000, 'auth', 'saml2'); + } + return true; } diff --git a/lang/en/auth_saml2.php b/lang/en/auth_saml2.php index 7c0c420e8..e8b5c518a 100644 --- a/lang/en/auth_saml2.php +++ b/lang/en/auth_saml2.php @@ -136,6 +136,8 @@ $string['multiidp:label:admin_help'] = 'Any users that log in using this IdP will automatically be made an site administrator'; $string['multiidp:label:whitelist'] = 'Redirected IP addresses'; $string['multiidp:label:whitelist_help'] = 'If set, it will force clients to this IdP. Format: xxx.xxx.xxx.xxx/bitmask. Separate multiple subnets on a new line.'; +$string['multiidp:label:protocolbinding'] = 'Protocol Binding'; +$string['multiidp:label:protocolbinding_help'] = 'This specifies which binding should be used to respond by the IdP when we send the AuthnRequest. The Binding must be supported by the IdP.'; $string['multiidpinfo'] = '
  • An IdP can only be used if it is set as Active
  • diff --git a/version.php b/version.php index 3f0726d04..6581735ab 100644 --- a/version.php +++ b/version.php @@ -24,8 +24,8 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2023100300; // The current plugin version (Date: YYYYMMDDXX). -$plugin->release = 2023100300; // Match release exactly to version. +$plugin->version = 2023112000; // The current plugin version (Date: YYYYMMDDXX). +$plugin->release = 2023112000; // Match release exactly to version. $plugin->requires = 2017051509; // Requires PHP 7, 2017051509 = T12. M3.3 // Strictly we require either Moodle 3.5 OR // we require Totara 3.3, but the version number From ebd2554ddbb6c250778c86387b7d205258d03eb9 Mon Sep 17 00:00:00 2001 From: Lars Mikal Rogne Date: Mon, 6 May 2024 08:30:08 +0200 Subject: [PATCH 2/2] Remove bindings which are not relevant in the context of IdP response to SP. --- classes/protocol_binding.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/classes/protocol_binding.php b/classes/protocol_binding.php index b21cf82f0..f769d97e4 100644 --- a/classes/protocol_binding.php +++ b/classes/protocol_binding.php @@ -16,8 +16,7 @@ class protocol_binding { public const HTTP_POST = 0; public const HTTP_ARTIFACT = 1; - public const HOK_SSO = 2; - public const HTTP_REDIRECT = 3; + /** * Map the internal id of the protocol bindings to the actual binding string. * @param int $id @@ -30,10 +29,6 @@ public static function get_binding(int $id): string { return 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'; case self::HTTP_ARTIFACT: return 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'; - case self::HOK_SSO: - return 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser'; - case self::HTTP_REDIRECT: - return 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'; default: throw new coding_exception('Invalid binding'); } @@ -42,8 +37,6 @@ public static function form_options(): array { return [ self::HTTP_POST => 'HTTP Post', self::HTTP_ARTIFACT => 'HTTP Artifact', - self::HOK_SSO => 'Holder-of-Key Web Browser SSO', - self::HTTP_REDIRECT => 'HTTP Redirect', ]; } }