Skip to content

Commit b7b2221

Browse files
Adds IDP settings
* en/disable moodle as an IDP. * Whitelist services by their <saml:Issuer>
1 parent bdc8222 commit b7b2221

File tree

4 files changed

+84
-23
lines changed

4 files changed

+84
-23
lines changed

idp/metadata.php

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,35 @@
3030

3131
$saml2auth = new \auth_saml2\auth();
3232

33-
$cert = file_get_contents($saml2auth->certcrt);
34-
$cert = preg_replace('~(-----(BEGIN|END) CERTIFICATE-----)|\n~', '', $cert);
35-
$baseurl = $CFG->wwwroot . '/auth/saml2/idp';
33+
if ($saml2auth->config->moodleidpenabled) {
34+
$download = optional_param('download', '', PARAM_RAW);
35+
if ($download) {
36+
header('Content-Disposition: attachment; filename=' . $saml2auth->spname . '.xml');
37+
}
3638

37-
$xml = <<<EOF
38-
<md:EntityDescriptor entityID="{$baseurl}/metadata.php" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
39-
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" WantAuthnRequestsSigned="false">
40-
<md:KeyDescriptor>
41-
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
42-
<X509Data><X509Certificate>{$cert}</X509Certificate></X509Data>
43-
</KeyInfo>
44-
</md:KeyDescriptor>
45-
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
46-
Location="{$baseurl}/slo.php" />
47-
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
48-
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
49-
Location="{$baseurl}/sso.php" />
50-
</md:IDPSSODescriptor>
51-
</md:EntityDescriptor>
52-
EOF;
39+
$cert = file_get_contents($saml2auth->certcrt);
40+
$cert = preg_replace('~(-----(BEGIN|END) CERTIFICATE-----)|\n~', '', $cert);
41+
$baseurl = $CFG->wwwroot . '/auth/saml2/idp';
5342

54-
header('Content-Type: text/xml');
55-
echo($xml);
43+
$xml = <<<EOF
44+
<md:EntityDescriptor entityID="{$baseurl}/metadata.php" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
45+
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" WantAuthnRequestsSigned="false">
46+
<md:KeyDescriptor>
47+
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
48+
<X509Data><X509Certificate>{$cert}</X509Certificate></X509Data>
49+
</KeyInfo>
50+
</md:KeyDescriptor>
51+
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
52+
Location="{$baseurl}/slo.php" />
53+
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
54+
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
55+
Location="{$baseurl}/sso.php" />
56+
</md:IDPSSODescriptor>
57+
</md:EntityDescriptor>
58+
EOF;
59+
60+
header('Content-Type: text/xml');
61+
echo($xml);
62+
} else {
63+
throw new saml2_exception('idp_enabled_error', get_string('moodleidpenabled_error', 'auth_saml2'));
64+
}

idp/sso.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131

3232
if (isguestuser()) {
3333
// Guest user not allowed here.
34-
// TODO: add exception.
35-
die;
34+
throw new saml2_exception('guest_error', get_string('moodleidpguest_error', 'auth_saml2'));
3635
}
3736

3837
// Get the request data.
@@ -55,6 +54,20 @@
5554
$destination = htmlspecialchars($xpath->evaluate('normalize-space(/*/@AssertionConsumerServiceURL)'));
5655
$sp = $xpath->evaluate('normalize-space(/*/*[local-name() = "Issuer"])');
5756

57+
// Confirm we know about this SP.
58+
$knownsps = [];
59+
foreach (explode(PHP_EOL, $saml2auth->config->moodleidpsplist) as $ksp) {
60+
$ksp = trim($ksp);
61+
if (empty($ksp)) {
62+
continue;
63+
}
64+
$knownsps[] = $ksp;
65+
}
66+
67+
if (!in_array($sp, $knownsps)) {
68+
throw new saml2_exception('unknown_sp_error', get_string('moodleidpsplist_error', 'auth_saml2', $sp));
69+
}
70+
5871
// Get time in UTC.
5972
$datetime = new DateTime();
6073
$datetime->setTimezone(new DatetimeZone('UTC'));

lang/en/auth_saml2.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@
128128
$string['metadatafetchfailed'] = 'Metadata fetch failed: {$a}';
129129
$string['metadatafetchfailedstatus'] = 'Metadata fetch failed: Status code {$a}';
130130
$string['metadatafetchfailedunknown'] = 'Metadata fetch failed: Unknown cURL error';
131+
$string['moodleidpdescription'] = 'Settings for Moodle as an Identity Provider for other services.';
132+
$string['moodleidpenabled'] = 'Enable IDP';
133+
$string['moodleidpenabled_error'] = 'Moodle IDP is not enabled. Check Settings.';
134+
$string['moodleidpenabled_help'] = 'Allow Moodle to act as an IDP for external services.';
135+
$string['moodleidpguest_error'] = 'Guest users cannot log in via SAML.';
136+
$string['moodleidpheading'] = 'Moodle IDP Settings';
137+
$string['moodleidpmetadata'] = 'IDP Metadata';
138+
$string['moodleidpmetadata_help'] = '<a href=\'{$a}\'>View Identity Provider Metadata</a> | <a href=\'{$a}?download=1\'>Download IDP Metadata</a>';
139+
$string['moodleidpsplist'] = 'Valid Issuers';
140+
$string['moodleidpsplist_error'] = 'Unknown service attempting to authenticate: {$a}. Check config.';
141+
$string['moodleidpsplist_help'] = 'List of services allowed to use this moodle as an IDP identified by the <code>saml:Issuer</code> tag in the SAML request. One per line. {$a->example}';
131142
$string['multiidp:label:displayname'] = 'Display name';
132143
$string['multiidp:label:alias'] = 'Alias';
133144
$string['multiidp:label:active'] = 'Active';

settings.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,4 +444,32 @@
444444
',',
445445
PARAM_TEXT,
446446
5));
447+
448+
// Moodle as an IDP feature setting section.
449+
$settings->add(new admin_setting_heading('auth_saml2/moodleidpheading', get_string('moodleidpheading', 'auth_saml2'),
450+
new lang_string('moodleidpdescription', 'auth_saml2')));
451+
452+
// Enable Moodle IDP.
453+
$settings->add(new admin_setting_configselect(
454+
'auth_saml2/moodleidpenabled',
455+
get_string('moodleidpenabled', 'auth_saml2'),
456+
get_string('moodleidpenabled_help', 'auth_saml2'),
457+
0, $yesno));
458+
459+
// IDP Metadata.
460+
$settings->add(new setting_textonly(
461+
'auth_saml2/moodleidpmetadata',
462+
get_string('moodleidpmetadata', 'auth_saml2'),
463+
get_string('moodleidpmetadata_help', 'auth_saml2', $CFG->wwwroot . '/auth/saml2/idp/metadata.php')
464+
));
465+
466+
// List valid SPs.
467+
$settings->add(new admin_setting_configtextarea(
468+
'auth_saml2/moodleidpsplist',
469+
get_string('moodleidpsplist', 'auth_saml2'),
470+
get_string('moodleidpsplist_help', 'auth_saml2', ['example' => "<pre>
471+
https://www.someothermoodle.com/auth/saml2/sp/metadata.php
472+
</pre>"]),
473+
'',
474+
PARAM_TEXT));
447475
}

0 commit comments

Comments
 (0)