Azure Plugin: Update to use oatuh2 - refs BT#8959

pull/2926/head
Angel Fernando Quiroz Campos 7 years ago
parent f600c2bbce
commit 0720401a00
  1. 10
      main/inc/lib/online.inc.php
  2. 18
      plugin/azure_active_directory/index.php
  3. 2
      plugin/azure_active_directory/lang/english.php
  4. 83
      plugin/azure_active_directory/src/AzureActiveDirectory.php
  5. 108
      plugin/azure_active_directory/src/callback.php
  6. 12
      plugin/azure_active_directory/view/block.tpl

@ -166,10 +166,12 @@ function online_logout($user_id = null, $logout_redirect = false)
$url = api_get_path(WEB_PATH).'index.php';
if ($logout_redirect && api_get_plugin_setting('azure_active_directory', 'enable') == 'true') {
$activeDirectoryPlugin = AzureActiveDirectory::create();
$azureLogout = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNOUT);
if (!empty($azureLogout)) {
$url = $azureLogout;
if (ChamiloSession::read('_user_auth_source') === 'azure_active_directory') {
$activeDirectoryPlugin = AzureActiveDirectory::create();
$azureLogout = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_LOGOUT);
if (!empty($azureLogout)) {
$url = $azureLogout;
}
}
}

@ -10,23 +10,7 @@
$activeDirectoryPlugin = AzureActiveDirectory::create();
if ($activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_ENABLE) === 'true') {
$signUp = $activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_SIGNIN_POLICY);
$signIn = $activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_SIGNUP_POLICY);
$signUnified = $activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_SIGNUNIFIED_POLICY);
$_template['block_title'] = $activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_BLOCK_NAME);
if ($signUp) {
$_template['signup_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNUP);
}
if ($signIn) {
$_template['signin_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNIN);
}
if ($signUnified) {
$_template['signunified_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNUNIFIED);
}
$_template['signout_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNOUT);
$_template['signin_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_AUTHORIZE);
}

@ -13,7 +13,7 @@ $strings['plugin_comment'] = 'Allow authentication with Microsoft\'s Azure Activ
$strings['enable'] = 'Enable';
$strings['app_id'] = 'Application ID';
$strings['app_id_help'] = 'Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609';
$strings['tenant'] = 'Tenant';
$strings['app_secret'] = 'Application secret';
$strings['tenant_help'] = 'Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com';
$strings['signup_policy'] = 'Sign up policy';
$strings['signup_policy_help'] = 'Enter your sign up policy name, e.g.g b2c_1_sign_up';

@ -1,6 +1,8 @@
<?php
/* For license terms, see /license.txt */
use TheNetworg\OAuth2\Client\Provider\Azure;
/**
* AzureActiveDirectory plugin class.
*
@ -12,15 +14,11 @@ class AzureActiveDirectory extends Plugin
{
const SETTING_ENABLE = 'enable';
const SETTING_APP_ID = 'app_id';
const SETTING_TENANT = 'tenant';
const SETTING_SIGNUP_POLICY = 'signup_policy';
const SETTING_SIGNIN_POLICY = 'signin_policy';
const SETTING_SIGNUNIFIED_POLICY = 'signunified_policy';
const SETTING_APP_SECRET = 'app_secret';
const SETTING_BLOCK_NAME = 'block_name';
const URL_TYPE_SIGNUP = 'sign-up';
const URL_TYPE_SIGNIN = 'sign-in';
const URL_TYPE_SIGNUNIFIED = 'sign-unified';
const URL_TYPE_SIGNOUT = 'sign-out';
const URL_TYPE_AUTHORIZE = 'login';
const URL_TYPE_LOGOUT = 'logout';
/**
* AzureActiveDirectory constructor.
@ -30,10 +28,7 @@ class AzureActiveDirectory extends Plugin
$settings = [
self::SETTING_ENABLE => 'boolean',
self::SETTING_APP_ID => 'text',
self::SETTING_TENANT => 'text',
self::SETTING_SIGNUP_POLICY => 'text',
self::SETTING_SIGNIN_POLICY => 'text',
self::SETTING_SIGNUNIFIED_POLICY => 'text',
self::SETTING_APP_SECRET => 'text',
self::SETTING_BLOCK_NAME => 'text',
];
@ -63,56 +58,34 @@ class AzureActiveDirectory extends Plugin
}
/**
* @param string $urlType Type of URL to generate
* @return Azure
*/
public function getProvider()
{
$provider = new Azure([
'clientId' => $this->get(self::SETTING_APP_ID),
'clientSecret' => $this->get(self::SETTING_APP_SECRET),
'redirectUri' => api_get_path(WEB_PLUGIN_PATH).'azure_active_directory/src/callback.php',
]);
return $provider;
}
/**
* @param $urlType Type of URL to generate
*
* @return string
*/
public function getUrl($urlType)
{
$settingsInfo = $this->get_settings();
$settings = [];
foreach ($settingsInfo as $settingInfo) {
$variable = str_replace($this->get_name().'_', '', $settingInfo['variable']);
$settings[$variable] = $settingInfo['selected_value'];
}
if (isset($settings[self::SETTING_TENANT])) {
$url = "https://login.microsoftonline.com/{$settings[self::SETTING_TENANT]}/oauth2/v2.0/";
} else {
return '';
}
$callback = api_get_path(WEB_PLUGIN_PATH).$this->get_name().'/src/callback.php';
if ($urlType === self::URL_TYPE_SIGNOUT) {
$action = 'logout';
$urlParams = [
'p' => $settings[self::SETTING_SIGNIN_POLICY],
'post_logout_redirect_uri' => $callback,
];
} else {
$action = 'authorize';
$policy = $settings[self::SETTING_SIGNUP_POLICY];
if ($urlType === self::URL_TYPE_SIGNIN) {
$policy = $settings[self::SETTING_SIGNIN_POLICY];
} elseif ($urlType === self::URL_TYPE_SIGNUNIFIED) {
$policy = $settings[self::SETTING_SIGNUNIFIED_POLICY];
}
if (self::URL_TYPE_LOGOUT === $urlType) {
$provider = $this->getProvider();
$urlParams = [
'client_id' => $settings[self::SETTING_APP_ID],
'response_type' => 'id_token',
'redirect_uri' => $callback,
'scope' => 'openid',
'response_mode' => 'form_post',
'state' => time(),
'nonce' => time(),
'p' => $policy,
];
return $provider->getLogoutUrl(
api_get_path(WEB_PATH)
);
}
return $url.$action.'?'.http_build_query($urlParams);
return api_get_path(WEB_PLUGIN_PATH).$this->get_name().'/src/callback.php';
}
}

@ -2,51 +2,79 @@
/* For license terms, see /license.txt */
require __DIR__.'/../../../main/inc/global.inc.php';
require_once __DIR__.'/../../../main/auth/external_login/functions.inc.php';
if (isset($_POST['error']) || empty($_REQUEST)) {
header('Location: '.api_get_path(WEB_PATH).'index.php?logout=logout');
$plugin = AzureActiveDirectory::create();
$provider = $plugin->getProvider();
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
ChamiloSession::write('oauth2state', $provider->getState());
header('Location: '.$authUrl);
exit;
}
// Check given state against previously stored one to mitigate CSRF attack
if (empty($_GET['state']) || ($_GET['state'] !== ChamiloSession::read('oauth2state'))) {
ChamiloSession::erase('oauth2state');
exit;
}
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code'],
'resource' => 'https://graph.windows.net',
]);
$me = null;
try {
$me = $provider->get("me", $token);
} catch (Exception $e) {
exit;
}
list($jwtHeader, $jwtPayload, $jwtSignature) = explode('.', $_REQUEST['id_token']);
$jwtHeader = json_decode(base64_decode($jwtHeader));
$jwtPayload = json_decode(base64_decode($jwtPayload));
$u = [
'firstname' => $jwtPayload->given_name,
'lastname' => $jwtPayload->family_name,
'status' => STUDENT,
'email' => $jwtPayload->emails[0],
'username' => $jwtPayload->emails[0],
'language' => 'en',
'password' => 'azure_active_directory',
'auth_source' => 'azure_active_directory '.$jwtPayload->idp,
'extra' => [],
];
$userInfo = api_get_user_info_from_email($jwtPayload->emails[0]);
if ($userInfo === false) {
// we have to create the user
$chamilo_uid = external_add_user($u);
if ($chamilo_uid !== false) {
$_user['user_id'] = $chamilo_uid;
$_user['uidReset'] = true;
$_SESSION['_user'] = $_user;
}
} else {
// User already exists, update info and login
$chamilo_uid = $userInfo['user_id'];
$u['user_id'] = $chamilo_uid;
external_update_user($u);
$_user['user_id'] = $chamilo_uid;
$_user['uidReset'] = true;
$_SESSION['_user'] = $_user;
$userInfo = [];
if (!empty($me['email'])) {
$userInfo = api_get_user_info_from_email($me['email']);
}
if (empty($userInfo) && !empty($me['email'])) {
$extraFieldValue = new ExtraFieldValue('user');
$itemValue = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
'organisationemail',
$me['email']
);
$userInfo = api_get_user_info($itemValue['item_id']);
}
if (empty($userInfo) && !empty($me['mailNickname'])) {
$extraFieldValue = new ExtraFieldValue('user');
$itemValue = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
'azure_id',
$me['mailNickname']
);
$userInfo = api_get_user_info($itemValue['item_id']);
}
if (empty($userInfo)) {
header('Location: '.api_get_path(WEB_PATH).'index.php?loginFailed=1&error=user_password_incorrect');
exit;
}
$_user['user_id'] = $userInfo['user_id'];
$_user['uidReset'] = true;
ChamiloSession::write('_user', $_user);
ChamiloSession::write('_user_auth_source', 'azure_active_directory');
header('Location: '.api_get_path(WEB_PATH));
exit;

@ -4,16 +4,6 @@
<h4>{{ azure_active_directory.block_title }}</h4>
{% endif %}
{% if not azure_active_directory.signin_url is empty %}
<a href="{{ azure_active_directory.signin_url }}" class="btn btn-default">{{ 'SignIn'|get_lang }}</a>
{% endif %}
{% if not azure_active_directory.signup_url is empty %}
<a href="{{ azure_active_directory.signup_url }}" class="btn btn-success">{{ 'SignUp'|get_lang }}</a>
{% endif %}
{% if not azure_active_directory.signunified_url is empty %}
<a href="{{ azure_active_directory.signunified_url }}" class="btn btn-info">{{ 'SignUpAndSignIn'|get_plugin_lang('AzureActiveDirectory') }}</a>
{% endif %}
<a href="{{ azure_active_directory.signin_url }}" class="btn btn-default">{{ 'SignIn'|get_lang }}</a>
</div>
{% endif %}

Loading…
Cancel
Save