From 918a1fb4b4616c4d1b1713f6ec531a660f0b8845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Pe=CC=81rez=20Crespo?= <jaime.perez@uninett.no> Date: Thu, 7 Sep 2017 15:48:07 +0200 Subject: [PATCH] Add a new method SimpleSAML\Auth\getProcessedURL(). This method allows us to parse a URL and "rebase" it based on the $config['application']['baseURL'] configuration option. Thanks to this, applications will be able to configure a canonical base URL for the application, effectively translating any URL that might be built incorrectly (e.g. not using HTTPS because that is offloaded to a reverse proxy). --- lib/SimpleSAML/Auth/Simple.php | 55 ++++++++++++++++++++++++++++++++-- lib/SimpleSAML/Utils/HTTP.php | 4 +-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php index 16e8c32e6..b95a0d4c9 100644 --- a/lib/SimpleSAML/Auth/Simple.php +++ b/lib/SimpleSAML/Auth/Simple.php @@ -4,6 +4,8 @@ namespace SimpleSAML\Auth; use \SimpleSAML_Auth_Source as Source; use \SimpleSAML_Auth_State as State; +use \SimpleSAML_Configuration as Configuration; +use \SimpleSAML_Error_AuthSource as AuthSourceError; use \SimpleSAML\Module; use \SimpleSAML_Session as Session; use \SimpleSAML\Utils\HTTP; @@ -21,8 +23,12 @@ class Simple * * @var string */ - private $authSource; + protected $authSource; + /** + * @var \SimpleSAML_Configuration|null + */ + protected $app_config; /** * Create an instance with the specified authsource. @@ -34,6 +40,7 @@ class Simple assert('is_string($authSource)'); $this->authSource = $authSource; + $this->app_config = Configuration::getInstance()->getConfigItem('application', null); } @@ -48,7 +55,7 @@ class Simple { $as = Source::getById($this->authSource); if ($as === null) { - throw new \SimpleSAML_Error_AuthSource($this->authSource, 'Unknown authentication source.'); + throw new AuthSourceError($this->authSource, 'Unknown authentication source.'); } return $as; } @@ -347,4 +354,48 @@ class Simple return $logout; } + + + /** + * Process a URL and modify it according to the application/baseURL configuration option, if present. + * + * @param string|null $url The URL to process, or null if we want to use the current URL. Both partial and full + * URLs can be used as a parameter. The maximum precedence is given to the application/baseURL configuration option, + * then the URL specified (if it specifies scheme, host and port) and finally the environment observed in the + * server. + * + * @return string The URL modified according to the precedence rules. + */ + protected function getProcessedURL($url = null) + { + if ($url === null) { + $url = HTTP::getSelfURL(); + } + + $scheme = parse_url($url, PHP_URL_SCHEME); + $host = parse_url($url, PHP_URL_HOST) ?: HTTP::getSelfHost(); + $port = parse_url($url, PHP_URL_PORT) ?: ( + $scheme ? '' : trim(HTTP::getServerPort(), ':') + ); + $scheme = $scheme ?: (HTTP::getServerHTTPS() ? 'https' : 'http'); + $path = parse_url($url, PHP_URL_PATH) ?: '/'; + $query = parse_url($url, PHP_URL_QUERY) ?: ''; + $fragment = parse_url($url, PHP_URL_FRAGMENT) ?: ''; + + $port = !empty($port) ? ':'.$port : ''; + if (($scheme === 'http' && $port === ':80') || ($scheme === 'https' && $port === ':443')) { + $port = ''; + } + + if (is_null($this->app_config)) { + // nothing more we can do here + return $scheme.'://'.$host.$port.$path.($query ? '?'.$query : '').($fragment ? '#'.$fragment : ''); + } + + $base = trim($this->app_config->getString( + 'baseURL', + $scheme.'://'.$host.$port + ), '/'); + return $base.$path.($query ? '?'.$query : '').($fragment ? '#'.$fragment : ''); + } } diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php index 1f6e50cdb..a05753827 100644 --- a/lib/SimpleSAML/Utils/HTTP.php +++ b/lib/SimpleSAML/Utils/HTTP.php @@ -81,7 +81,7 @@ class HTTP * * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> */ - private static function getServerHTTPS() + public static function getServerHTTPS() { if (!array_key_exists('HTTPS', $_SERVER)) { // not an https-request @@ -106,7 +106,7 @@ class HTTP * * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> */ - private static function getServerPort() + public static function getServerPort() { $port = (isset($_SERVER['SERVER_PORT'])) ? $_SERVER['SERVER_PORT'] : '80'; if (self::getServerHTTPS()) { -- GitLab