Moodle SSO Integration Guide
Some of our application partners use the Moodle platform to deliver their content and manage courses. It may be helpful to build out Clever SSO integration to allow users to more easily access this content. While this integration can be set up with minimal development work, there are aspects of it that may still require engineering based on your needs.
SSO Integrations Only
Please note that this guide is meant for Clever SSO integrations with Moodle only and does not include any guidance for rostering.
OAuth with Moodle
Moodle Version
This guide is written with version 4.0 in mind. If you are working with a different version of Moodle, some aspects may not apply.
To get SSO working, we will need to set up an OAuth connection. You will need administrator access. On the Site administration page, navigate to Server
Next, select "OAuth 2 services"
Configuration - Clever
In newer versions of Moodle, you should see an option to create a new "Clever" service. Selecting this option, will pre-populate some fields in the configuration page. At this stage, all you need to do is provide a Client ID and Client secret. These can be found in your Clever application developer dashboard Settings.
Once you've provided your client credentials, you are done! You have effectively set up SSO between your Moodle instance and Clever. Navigating to your login page, you should now see a Clever login button.
Configuration - Custom
If you do not see the option to create a Clever service in your Moodle instance, select "Custom". You will have additional configuration steps involving authentication endpoints and field mappings. Please see the screenshots below:
authorization_endpoint: https://clever.com/oauth/authorize
token_endpoint: https://clever.com/oauth/tokens
userinfo_endpoint: https://api.clever.com/v3.0/me
userdata_endpoint: https://api.clever.com/v3.0/users
data-id: idnumber
data-name-first: firstname
data-name-last: lastname
data-email: email
Once you've set up the field mappings and
Clever-initiated Logins and the State Param
Many Clever users will launch SSO from the Clever Portal, which is Clever's SSO launchpad page. See the screenshot below as an example:
By default, your Moodle-Clever SSO integration is unable to handle authentication requests that are kicked off from the Clever Portal. This is because Moodle requires a state parameter for authentication requests in order to prevent CSRF attacks.
If your integration is not set up to handle this, you will see the following error message when authentication is initiated from the Clever Portal into your Moodle instance.
To handle authentication requests initiated from the Clever Portal, we'll need to re-initiate the authentication request from our Moodle application with the state parameter appended. Clever will pass the state parameter through so all you need to do is adjust the authentication service to handle this use case.
In your Moodle source code files, navigate to /admin/oauth2callback.php.
Here, you will want to process Clever-initiated SSO requests that are missing state parameters by creating a new request and formulating it to include a state parameter. See an example workflow below:
$state = optional_param('state', '', PARAM_RAW);
if ($state == '') {
/*print_error('missing state');*/
$stateparams['wantsurl'] = new moodle_url('/');
$stateparams['sesskey'] = sesskey();
$stateparams['id'] = $issuer->get('id');
//Include all relevant params for the new authentication request
$params = array_merge(
[
'client_id' => $issuer->get('clientid'),
'redirect_uri' => new moodle_url('/admin/oauth2callback.php'),
'response_type' => 'code',
'scope' => optional_param('scope', null, PARAM_RAW),
'code' => optional_param('code', null, PARAM_RAW),
'state' => new moodle_url('/auth/oauth2/login.php', $stateparams),
]
);
//Formulate a new SSO request URL with the necessary params
$backtocleverurl = new moodle_url($clever_url, $params);
error_log("*****************admincallback backtocleverurl redirect back to clever");
error_log(print_r($backtocleverurl, true));
redirect($backtocleverurl);
} else {
// The authorization code generated by the authorization server.
$code = required_param('code', PARAM_RAW);
// The state parameter we've given (used in moodle as a redirect url).
$state = required_param('state', PARAM_LOCALURL);
error_log("admincallback state");
error_log(print_r($state, true));
$redirecturl = new moodle_url($state);
$params = $redirecturl->params();
if (isset($params['sesskey']) and confirm_sesskey($params['sesskey'])) {
$redirecturl->param('oauth2code', $code);
redirect($redirecturl);
} else {
print_error('invalidsesskey');
}
}
Updated 8 months ago