コード例 #1
0
ファイル: Context.class.php プロジェクト: rhymix/rhymix
 /**
  * Single Sign On (SSO)
  *
  * @return bool True : Module handling is necessary in the control path of current request , False : Otherwise
  */
 public function checkSSO()
 {
     // pass if it's not GET request or XE is not yet installed
     if (!config('use_sso') || Rhymix\Framework\UA::isRobot()) {
         return TRUE;
     }
     $checkActList = array('rss' => 1, 'atom' => 1);
     if (self::getRequestMethod() != 'GET' || !self::isInstalled() || isset($checkActList[self::get('act')])) {
         return TRUE;
     }
     // pass if default URL is not set
     $default_url = trim($this->db_info->default_url);
     if (!$default_url) {
         return TRUE;
     }
     if (substr_compare($default_url, '/', -1) !== 0) {
         $default_url .= '/';
     }
     // Get current site information (only the base URL, not the full URL)
     $current_site = self::getRequestUri();
     // Step 1: if the current site is not the default site, send SSO validation request to the default site
     if ($default_url !== $current_site && !self::get('sso_response') && $_COOKIE['sso'] !== md5($current_site)) {
         // Set sso cookie to prevent multiple simultaneous SSO validation requests
         setcookie('sso', md5($current_site), 0, '/');
         // Redirect to the default site
         $sso_request = Rhymix\Framework\Security::encrypt(Rhymix\Framework\URL::getCurrentURL());
         $redirect_url = $default_url . '?sso_request=' . urlencode($sso_request);
         header('Location:' . $redirect_url);
         return false;
     }
     // Step 2: receive and process SSO validation request at the default site
     if ($default_url === $current_site && self::get('sso_request')) {
         // Get the URL of the origin site
         $sso_request = Rhymix\Framework\Security::decrypt(self::get('sso_request'));
         if (!$sso_request || !preg_match('!^https?://!', $sso_request)) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
             return false;
         }
         // Check that the origin site is a valid site in this XE installation (to prevent open redirect vuln)
         if (!getModel('module')->getSiteInfoByDomain(rtrim($url, '/'))->site_srl) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
             return false;
         }
         // Redirect back to the origin site
         $sso_response = Rhymix\Framework\Security::encrypt(session_id());
         header('Location: ' . Rhymix\Framework\URL::modifyURL($sso_request, array('sso_response' => $sso_response)));
         return false;
     }
     // Step 3: back at the origin site, set session ID to be the same as the default site
     if ($default_url !== $current_site && self::get('sso_response')) {
         // Check SSO response
         $sso_response = Rhymix\Framework\Security::decrypt(self::get('sso_response'));
         if ($sso_response === false) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
             return false;
         }
         // 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) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
             return false;
         }
         // Set session ID
         setcookie(session_name(), $sso_response);
         // Finally, redirect to the originally requested URL
         header('Location: ' . Rhymix\Framework\URL::getCurrentURL(array('sso_response' => null)));
         return false;
     }
     // If none of the conditions above apply, proceed normally
     return TRUE;
 }