Update SSO mechanism to use new domain system

This commit is contained in:
Kijin Sung 2017-03-04 22:05:16 +09:00
parent 4bde9f6c7b
commit 8cf3d7b520
3 changed files with 35 additions and 45 deletions

View file

@ -265,10 +265,6 @@ class Context
self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null); self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null);
self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null); self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null);
self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none'); self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none');
if($site_module_info->site_srl && isSiteID($site_module_info->domain))
{
self::set('vid', $site_module_info->domain, TRUE);
}
} }
else else
{ {
@ -336,6 +332,7 @@ class Context
// start session // start session
$relax_key_checks = ($this->act === 'procFileUpload' && preg_match('/shockwave\s?flash/i', $_SERVER['HTTP_USER_AGENT'])); $relax_key_checks = ($this->act === 'procFileUpload' && preg_match('/shockwave\s?flash/i', $_SERVER['HTTP_USER_AGENT']));
Rhymix\Framework\Session::checkSSO($site_module_info);
Rhymix\Framework\Session::start(false, $relax_key_checks); Rhymix\Framework\Session::start(false, $relax_key_checks);
$this->_COOKIE = $_COOKIE; $this->_COOKIE = $_COOKIE;
@ -660,7 +657,7 @@ class Context
*/ */
public function checkSSO() public function checkSSO()
{ {
return !Rhymix\Framework\Session::checkSSO(); return true;
} }
/** /**

View file

@ -270,87 +270,87 @@ class Session
* This method uses more or less the same logic as XE's SSO mechanism. * This method uses more or less the same logic as XE's SSO mechanism.
* It may need to be changed to a more secure mechanism later. * It may need to be changed to a more secure mechanism later.
* *
* @return bool * @param object $site_module_info
* @return void
*/ */
public static function checkSSO() public static function checkSSO($site_module_info)
{ {
// Abort if SSO is disabled, the visitor is a robot, or this is not a typical GET request. // Abort if SSO is disabled, the visitor is a robot, or this is not a typical GET request.
if ($_SERVER['REQUEST_METHOD'] !== 'GET' || !config('use_sso') || UA::isRobot() || in_array(\Context::get('act'), array('rss', 'atom'))) if ($_SERVER['REQUEST_METHOD'] !== 'GET' || !config('use_sso') || UA::isRobot() || in_array(\Context::get('act'), array('rss', 'atom')))
{ {
return false; return;
}
// Abort of the default URL is not set.
$default_url = \Context::getDefaultUrl();
if (!$default_url)
{
return false;
} }
// Get the current site information. // Get the current site information.
$current_url = URL::getCurrentURL(); $is_default_domain = ($site_module_info->domain_srl == 0);
$current_host = parse_url($current_url, \PHP_URL_HOST); if (!$is_default_domain)
$default_host = parse_url($default_url, \PHP_URL_HOST); {
$current_domain = $site_module_info->domain;
$current_url = URL::getCurrentUrl();
$default_domain = getModel('module')->getSiteInfo(0);
$default_url = \Context::getDefaultUrl($default_domain);
}
// Step 1: if the current site is not the default site, send SSO validation request to the default site. // Step 1: if the current site is not the default site, send SSO validation request to the default site.
if($default_host !== $current_host && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_host)) if(!$is_default_domain && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_domain))
{ {
// Set sso cookie to prevent multiple simultaneous SSO validation requests. // Set sso cookie to prevent multiple simultaneous SSO validation requests.
setcookie('sso', md5($current_host), 0, '/'); setcookie('sso', md5($current_domain), 0, '/');
// Redirect to the default site. // Redirect to the default site.
$sso_request = Security::encrypt($current_url); $sso_request = Security::encrypt($current_url);
header('Location:' . URL::modifyURL($default_url, array('sso_request' => $sso_request))); header('Location:' . URL::modifyURL($default_url, array('sso_request' => $sso_request)));
return true; exit;
} }
// Step 2: receive and process SSO validation request at the default site. // Step 2: receive and process SSO validation request at the default site.
if($default_host === $current_host && \Context::get('sso_request')) if($is_default_domain && \Context::get('sso_request'))
{ {
// Get the URL of the origin site // Get the URL of the origin site
$sso_request = Security::decrypt(\Context::get('sso_request')); $sso_request = Security::decrypt(\Context::get('sso_request'));
if (!$sso_request || !preg_match('!^https?://!', $sso_request)) if (!$sso_request || !preg_match('!^https?://!', $sso_request))
{ {
\Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); \Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
return true; exit;
} }
// Redirect back to the origin site. // Encrypt the session ID.
self::start(true);
$sso_response = Security::encrypt(session_id()); $sso_response = Security::encrypt(session_id());
// Redirect back to the origin site.
header('Location: ' . URL::modifyURL($sso_request, array('sso_response' => $sso_response))); header('Location: ' . URL::modifyURL($sso_request, array('sso_response' => $sso_response)));
return true; self::close();
exit;
} }
// Step 3: back at the origin site, set session ID to be the same as the default site. // Step 3: back at the origin site, set session ID to be the same as the default site.
if($default_host !== $current_host && \Context::get('sso_response')) if(!$is_default_domain && \Context::get('sso_response'))
{ {
// Check SSO response // Check SSO response
$sso_response = Security::decrypt(\Context::get('sso_response')); $sso_response = Security::decrypt(\Context::get('sso_response'));
if ($sso_response === false) if ($sso_response === false)
{ {
\Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); \Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
return true; exit;
} }
// Check that the response was given by the default site (to prevent session fixation CSRF). // Check that the response was given by the default site (to prevent session fixation CSRF).
if(isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $default_url) !== 0) if(isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $default_url) !== 0)
{ {
\Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); \Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
return true; exit;
} }
// Set session ID. // Set the session ID.
self::close();
session_id($sso_response); session_id($sso_response);
self::start(); self::start(true, false);
// Finally, redirect to the originally requested URL. // Finally, redirect to the originally requested URL.
header('Location: ' . URL::getCurrentURL(array('sso_response' => null))); header('Location: ' . URL::getCurrentURL(array('sso_response' => null)));
return true; self::close();
exit;
} }
// If none of the conditions above apply, proceed normally.
return false;
} }
/** /**

View file

@ -47,17 +47,10 @@ $oContext = Context::getInstance();
$oContext->init(); $oContext->init();
/** /**
* @brief If default_url is set and it is different from the current url, attempt to redirect for SSO authentication and then process the module * @brief Initialize and execute Module Handler
**/ **/
if($oContext->checkSSO()) $oModuleHandler = new ModuleHandler();
{ $oModuleHandler->init() && $oModuleHandler->displayContent($oModuleHandler->procModule());
$oModuleHandler = new ModuleHandler();
if($oModuleHandler->init())
{
$oModuleHandler->displayContent($oModuleHandler->procModule());
}
}
Context::close(); Context::close();