Actualización
This commit is contained in:
27
main/auth/okn/metadata.php
Normal file
27
main/auth/okn/metadata.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/* For license terms, see /license.txt */
|
||||
|
||||
use OneLogin\Saml2\Settings;
|
||||
|
||||
require_once '../../../main/inc/global.inc.php';
|
||||
|
||||
/**
|
||||
* SAML Metadata view.
|
||||
*/
|
||||
require_once 'settings.php';
|
||||
|
||||
try {
|
||||
// Now we only validate SP settings
|
||||
$settings = new Settings($settingsInfo, true);
|
||||
$metadata = $settings->getSPMetadata();
|
||||
$errors = $settings->validateMetadata($metadata);
|
||||
if (empty($errors)) {
|
||||
header('Content-Type: text/xml');
|
||||
echo $metadata;
|
||||
} else {
|
||||
throw new OneLogin\Saml2\Error('Invalid SP metadata: '.implode(', ', $errors), OneLogin\Saml2\Error::METADATA_SP_INVALID);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
15
main/auth/okn/report.php
Normal file
15
main/auth/okn/report.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
require_once '../../../main/inc/global.inc.php';
|
||||
|
||||
if (isset($_REQUEST['key']) && isset($_REQUEST['username'])) {
|
||||
$securityKey = api_get_configuration_value('security_key');
|
||||
$result = api_is_valid_secret_key($_REQUEST['key'], $securityKey);
|
||||
if ($result) {
|
||||
$userInfo = api_get_user_info_from_username($_REQUEST['username']);
|
||||
if ($userInfo) {
|
||||
$result = Tracking::getCourseLpProgress($userInfo['id'], 0);
|
||||
echo json_encode($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
157
main/auth/okn/settings.dist.php
Normal file
157
main/auth/okn/settings.dist.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
exit;
|
||||
|
||||
require_once '../../../main/inc/global.inc.php';
|
||||
|
||||
$spBaseUrl = api_get_path(WEB_CODE_PATH).'auth/okn/';
|
||||
|
||||
$url = 'https://example.es/';
|
||||
$realm = 'master';
|
||||
$path = '/path';
|
||||
|
||||
//$certificate = file_get_contents($path);
|
||||
|
||||
$settingsInfo = [
|
||||
'course_list' => ['ABC', 'CDE'],
|
||||
'strict' => false,
|
||||
'debug' => true,
|
||||
'sp' => [
|
||||
'entityId' => $spBaseUrl.'metadata.php',
|
||||
'assertionConsumerService' => [
|
||||
'url' => $spBaseUrl.'start.php?acs',
|
||||
],
|
||||
'singleLogoutService' => [
|
||||
'url' => $spBaseUrl.'start.php?sls',
|
||||
],
|
||||
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
|
||||
],
|
||||
'idp' => [
|
||||
'entityId' => $url.'auth/realms/'.$realm, // Example http://localhost:8080/auth/realms/master
|
||||
'singleSignOnService' => [
|
||||
'url' => $url.'auth/realms/'.$realm.'/protocol/saml', // example http://localhost:8080/auth/realms/master/protocol/saml
|
||||
],
|
||||
'singleLogoutService' => [
|
||||
'url' => $url.'auth/realms/'.$realm.'/protocol/saml', // example http://localhost:8080/auth/realms/master/protocol/saml
|
||||
],
|
||||
//'x509cert' => $certificate,
|
||||
],
|
||||
];
|
||||
|
||||
// advanced settings
|
||||
//
|
||||
//
|
||||
//// Compression settings
|
||||
//'compress' => array (
|
||||
// 'requests' => true,
|
||||
// 'responses' => true
|
||||
//),
|
||||
// // Security settings
|
||||
// 'security' => array (
|
||||
//
|
||||
// /** signatures and encryptions offered */
|
||||
//
|
||||
// // Indicates that the nameID of the <samlp:logoutRequest> sent by this SP
|
||||
// // will be encrypted.
|
||||
// 'nameIdEncrypted' => false,
|
||||
//
|
||||
// // Indicates whether the <samlp:AuthnRequest> messages sent by this SP
|
||||
// // will be signed. [Metadata of the SP will offer this info]
|
||||
// 'authnRequestsSigned' => false,
|
||||
//
|
||||
// // Indicates whether the <samlp:logoutRequest> messages sent by this SP
|
||||
// // will be signed.
|
||||
// 'logoutRequestSigned' => false,
|
||||
//
|
||||
// // Indicates whether the <samlp:logoutResponse> messages sent by this SP
|
||||
// // will be signed.
|
||||
// 'logoutResponseSigned' => false,
|
||||
//
|
||||
// /* Sign the Metadata
|
||||
// False || True (use sp certs) || array (
|
||||
// keyFileName => 'metadata.key',
|
||||
// certFileName => 'metadata.crt'
|
||||
// )
|
||||
// */
|
||||
// 'signMetadata' => false,
|
||||
//
|
||||
// /** signatures and encryptions required **/
|
||||
//
|
||||
// // Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest>
|
||||
// // and <samlp:LogoutResponse> elements received by this SP to be signed.
|
||||
// 'wantMessagesSigned' => false,
|
||||
//
|
||||
// // Indicates a requirement for the <saml:Assertion> elements received by
|
||||
// // this SP to be encrypted.
|
||||
// 'wantAssertionsEncrypted' => false,
|
||||
//
|
||||
// // Indicates a requirement for the <saml:Assertion> elements received by
|
||||
// // this SP to be signed. [Metadata of the SP will offer this info]
|
||||
// 'wantAssertionsSigned' => false,
|
||||
//
|
||||
// // Indicates a requirement for the NameID element on the SAMLResponse
|
||||
// // received by this SP to be present.
|
||||
// 'wantNameId' => true,
|
||||
//
|
||||
// // Indicates a requirement for the NameID received by
|
||||
// // this SP to be encrypted.
|
||||
// 'wantNameIdEncrypted' => false,
|
||||
//
|
||||
// // Authentication context.
|
||||
// // Set to false and no AuthContext will be sent in the AuthNRequest.
|
||||
// // Set true or don't present this parameter and you will get an AuthContext 'exact' 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport'.
|
||||
// // Set an array with the possible auth context values: array ('urn:oasis:names:tc:SAML:2.0:ac:classes:Password', 'urn:oasis:names:tc:SAML:2.0:ac:classes:X509').
|
||||
// 'requestedAuthnContext' => true,
|
||||
//
|
||||
// // Indicates if the SP will validate all received xmls.
|
||||
// // (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true).
|
||||
// 'wantXMLValidation' => true,
|
||||
//
|
||||
// // If true, SAMLResponses with an empty value at its Destination
|
||||
// // attribute will not be rejected for this fact.
|
||||
// 'relaxDestinationValidation' => false,
|
||||
//
|
||||
// // Algorithm that the toolkit will use on signing process. Options:
|
||||
// // 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
|
||||
// // 'http://www.w3.org/2000/09/xmldsig#dsa-sha1'
|
||||
// // 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
|
||||
// // 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'
|
||||
// // 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'
|
||||
// // Notice that sha1 is a deprecated algorithm and should not be used
|
||||
// 'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
||||
//
|
||||
// // Algorithm that the toolkit will use on digest process. Options:
|
||||
// // 'http://www.w3.org/2000/09/xmldsig#sha1'
|
||||
// // 'http://www.w3.org/2001/04/xmlenc#sha256'
|
||||
// // 'http://www.w3.org/2001/04/xmldsig-more#sha384'
|
||||
// // 'http://www.w3.org/2001/04/xmlenc#sha512'
|
||||
// // Notice that sha1 is a deprecated algorithm and should not be used
|
||||
// 'digestAlgorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
|
||||
//
|
||||
// // ADFS URL-Encodes SAML data as lowercase, and the toolkit by default uses
|
||||
// // uppercase. Turn it True for ADFS compatibility on signature verification
|
||||
// 'lowercaseUrlencoding' => false,
|
||||
//),
|
||||
//
|
||||
// // Contact information template, it is recommended to supply a
|
||||
// // technical and support contacts.
|
||||
// 'contactPerson' => array (
|
||||
// 'technical' => array (
|
||||
// 'givenName' => 'example',
|
||||
// 'emailAddress' => 'test@example.org'
|
||||
// ),
|
||||
// 'support' => array (
|
||||
// 'givenName' => 'example',
|
||||
// 'emailAddress' => 'test@example.org'
|
||||
// ),
|
||||
//),
|
||||
//
|
||||
// // Organization information template, the info in en_US lang is
|
||||
// // recomended, add more if required.
|
||||
// 'organization' => array (
|
||||
// 'en-US' => array(
|
||||
// 'name' => 'chamilo',
|
||||
// 'displayname' => 'chamilo',
|
||||
// 'url' => 'chamilo.org'
|
||||
// ),
|
||||
//),
|
||||
254
main/auth/okn/start.php
Normal file
254
main/auth/okn/start.php
Normal file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
/* For licensing terms, see /license.txt */
|
||||
|
||||
use ChamiloSession as Session;
|
||||
use OneLogin\Saml2\Auth;
|
||||
use OneLogin\Saml2\AuthnRequest;
|
||||
use OneLogin\Saml2\Settings;
|
||||
|
||||
require_once '../../../main/inc/global.inc.php';
|
||||
|
||||
// Create a settings.dist.php
|
||||
if (file_exists('settings.php')) {
|
||||
require_once 'settings.php';
|
||||
} else {
|
||||
$message = '';
|
||||
if (api_is_platform_admin()) {
|
||||
$message = 'Create a settings.php';
|
||||
}
|
||||
api_not_allowed(true, $message);
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$auth = new Auth($settingsInfo);
|
||||
$settings = new Settings($settingsInfo);
|
||||
$authRequest = new AuthnRequest($settings);
|
||||
|
||||
$samlRequest = $authRequest->getRequest(true);
|
||||
$idpData = $settings->getIdPData();
|
||||
|
||||
if (isset($_GET['email']) || isset($_GET['email_bis'])) {
|
||||
$auth->login();
|
||||
// If AuthNRequest ID need to be saved in order to later validate it, do instead
|
||||
/*$ssoBuiltUrl = $auth->login(null, [], false, false, true);
|
||||
$_SESSION['AuthNRequestID'] = $auth->getLastRequestID();
|
||||
header('Pragma: no-cache');
|
||||
header('Cache-Control: no-cache, must-revalidate');
|
||||
header('Location: ' . $ssoBuiltUrl);
|
||||
exit();*/
|
||||
} elseif (isset($_GET['slo'])) {
|
||||
$returnTo = null;
|
||||
$parameters = [];
|
||||
$nameId = Session::read('samlNameId');
|
||||
$sessionIndex = Session::read('samlSessionIndex');
|
||||
$nameIdFormat = Session::read('samlNameIdFormat');
|
||||
$auth->logout($returnTo, $parameters, $nameId, $sessionIndex, false, $nameIdFormat);
|
||||
} elseif (isset($_GET['acs'])) {
|
||||
$requestID = Session::read('AuthNRequestID');
|
||||
$auth->processResponse($requestID);
|
||||
$errors = $auth->getErrors();
|
||||
if (!empty($errors)) {
|
||||
$content .= '<p>'.implode(', ', $errors).'</p>';
|
||||
}
|
||||
|
||||
if (!$auth->isAuthenticated()) {
|
||||
api_not_allowed(true, $content.'<p>Not authenticated</p>');
|
||||
exit;
|
||||
}
|
||||
|
||||
$attributes = $auth->getAttributes();
|
||||
|
||||
$valueList = [];
|
||||
$attributeNameList = [
|
||||
'email',
|
||||
'username',
|
||||
'firstname',
|
||||
'lastname1',
|
||||
'lastname2',
|
||||
'courses',
|
||||
];
|
||||
|
||||
// Check normal params
|
||||
foreach ($attributeNameList as $name) {
|
||||
if (isset($attributes[$name]) && !empty($attributes[$name])) {
|
||||
$valueList[$name] = $attributes[$name];
|
||||
}
|
||||
}
|
||||
|
||||
// Check bis params
|
||||
foreach ($attributeNameList as $name) {
|
||||
$bisName = $name.'_bis';
|
||||
if (isset($attributes[$bisName]) && !empty($attributes[$bisName])) {
|
||||
$valueList[$name] = $attributes[$bisName];
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = $valueList;
|
||||
|
||||
if (!isset($attributes['email']) ||
|
||||
!isset($attributes['firstname']) ||
|
||||
!isset($attributes['lastname1']) ||
|
||||
!isset($attributes['lastname2']) ||
|
||||
!isset($attributes['username'])
|
||||
) {
|
||||
echo 'Not enough parameters, current values: ';
|
||||
echo '<pre>';
|
||||
var_dump($auth->getAttributes());
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($attributes as &$attribute) {
|
||||
$attribute = implode('', $attribute);
|
||||
}
|
||||
|
||||
$username = $attributes['username'];
|
||||
$userInfo = api_get_user_info_from_username($username);
|
||||
$userId = null;
|
||||
|
||||
if (empty($userInfo)) {
|
||||
$lastName = $attributes['lastname1'].' '.$attributes['lastname2'];
|
||||
$userId = UserManager::create_user(
|
||||
$attributes['firstname'],
|
||||
$lastName,
|
||||
STUDENT,
|
||||
$attributes['email'],
|
||||
$username,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'okn'
|
||||
);
|
||||
if ($userId) {
|
||||
$userInfo = api_get_user_info($userId);
|
||||
} else {
|
||||
echo "Error cannot create user: $username";
|
||||
}
|
||||
} else {
|
||||
// Only load users that were created using this method.
|
||||
if ($userInfo['auth_source'] === 'okn') {
|
||||
$userId = $userInfo['user_id'];
|
||||
} else {
|
||||
echo "Error cannot handle user $username, because it was not created by okn";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($userId)) {
|
||||
$courseCode = null;
|
||||
if (isset($settingsInfo['course_list']) && !empty($settingsInfo['course_list'])) {
|
||||
foreach ($settingsInfo['course_list'] as $courseCode) {
|
||||
CourseManager::subscribeUser($userId, $courseCode, STUDENT, 0, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($attributes['courses']) && !empty($attributes['courses'])) {
|
||||
$courses = explode(',', $attributes['courses']);
|
||||
$firstCourseCode = '';
|
||||
if (!empty($courses)) {
|
||||
$counter = 1;
|
||||
foreach ($courses as $course) {
|
||||
$courseInfo = api_get_course_info($course);
|
||||
if ($courseInfo) {
|
||||
if ($counter == 1) {
|
||||
$firstCourseCode = $course;
|
||||
}
|
||||
CourseManager::subscribeUser($userId, $courseInfo['code'], STUDENT, 0, 0, false);
|
||||
}
|
||||
$counter++;
|
||||
}
|
||||
$courseCode = $firstCourseCode;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean flash messages
|
||||
Session::write('flash_messages', '');
|
||||
|
||||
// Set chamilo sessions
|
||||
Session::write('samlUserdata', $auth->getAttributes());
|
||||
Session::write('samlNameId', $auth->getNameId());
|
||||
Session::write('samlNameIdFormat', $auth->getNameIdFormat());
|
||||
Session::write('samlSessionIndex', $auth->getSessionIndex());
|
||||
Session::erase('AuthNRequestID');
|
||||
|
||||
// Filling session variables with new data
|
||||
Session::write('_uid', $userId);
|
||||
Session::write('_user', $userInfo);
|
||||
Session::write('is_platformAdmin', false);
|
||||
Session::write('is_allowedCreateCourse', false);
|
||||
|
||||
Event::eventLogin($userId);
|
||||
|
||||
if (!empty($courseCode)) {
|
||||
$courseInfo = api_get_course_info($courseCode);
|
||||
header('Location: '.$courseInfo['course_public_url']);
|
||||
exit;
|
||||
}
|
||||
header('Location: '.api_get_path(WEB_PATH).'user_portal.php');
|
||||
exit;
|
||||
} else {
|
||||
echo 'User not found';
|
||||
}
|
||||
exit;
|
||||
|
||||
if (!empty($userId)) {
|
||||
} else {
|
||||
Display::addFlash(Display::return_message(get_lang('InvalidId')));
|
||||
}
|
||||
|
||||
/*if (isset($_POST['RelayState']) && \OneLogin\Saml2\Utils::getSelfURL() != $_POST['RelayState']) {
|
||||
$auth->redirectTo($_POST['RelayState']);
|
||||
}*/
|
||||
header('Location: '.api_get_path(WEB_PATH));
|
||||
exit;
|
||||
} elseif (isset($_GET['sls'])) {
|
||||
$requestID = Session::read('LogoutRequestID');
|
||||
$auth->processSLO(false, $requestID);
|
||||
$errors = $auth->getErrors();
|
||||
|
||||
if (empty($errors)) {
|
||||
Session::erase('samlNameId');
|
||||
Session::erase('samlSessionIndex');
|
||||
Session::erase('samlNameIdFormat');
|
||||
Session::erase('samlUserdata');
|
||||
Session::erase('AuthNRequestID');
|
||||
Session::erase('LogoutRequestID');
|
||||
|
||||
Display::addFlash(Display::return_message('Sucessfully logged out'));
|
||||
header('Location: '.api_get_path(WEB_PATH));
|
||||
exit;
|
||||
} else {
|
||||
api_not_allowed(true, implode(', ', $errors));
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template('');
|
||||
|
||||
if (isset($_SESSION['samlUserdata'])) {
|
||||
$attributes = Session::read('samlUserdata');
|
||||
$params = [];
|
||||
if (!empty($attributes)) {
|
||||
$content .= 'You have the following attributes:<br>';
|
||||
$content .= '<table class="table"><thead><th>Name</th><th>Values</th></thead><tbody>';
|
||||
foreach ($attributes as $attributeName => $attributeValues) {
|
||||
$content .= '<tr><td>'.htmlentities($attributeName).'</td><td><ul>';
|
||||
foreach ($attributeValues as $attributeValue) {
|
||||
$content .= '<li>'.htmlentities($attributeValue).'</li>';
|
||||
}
|
||||
$content .= '</ul></td></tr>';
|
||||
}
|
||||
$content .= '</tbody></table>';
|
||||
} else {
|
||||
$content .= "<p>You don't have any attribute</p>";
|
||||
}
|
||||
|
||||
$content .= '<p><a href="?slo" >Logout</a></p>';
|
||||
} else {
|
||||
$content .= '<p><a href="?sso" >Login</a></p>';
|
||||
//$content .= '<p><a href="?sso2" >Login and access to attrs.php page</a></p>';
|
||||
}
|
||||
|
||||
$template->assign('content', $content);
|
||||
$template->display_one_col_template();
|
||||
Reference in New Issue
Block a user