From b95b0229baf33d59dc271f46710fc50aba2b0655 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaime=20Pe=CC=81rez=20Crespo?= <jaime.perez@uninett.no>
Date: Mon, 16 Oct 2017 12:24:16 +0200
Subject: [PATCH] Add a configuration option to specify the base URL for the
 application protected.

---
 config-templates/config.php   | 22 ++++++++++++++++++++++
 lib/SimpleSAML/Utils/HTTP.php | 25 ++++++++++++++++++-------
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/config-templates/config.php b/config-templates/config.php
index 0fafbdc7c..18f88fd7f 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -30,6 +30,28 @@ $config = array(
      */
     'baseurlpath' => 'simplesaml/',
 
+    /*
+     * The 'application' configuration array groups a set configuration options
+     * relative to an application protected by SimpleSAMLphp.
+     */
+    //'application' => array(
+        /*
+         * The 'baseURL' configuration option allows you to specify a protocol,
+         * host and optionally a port that serves as the canonical base for all
+         * your application's URLs. This is useful when the environment
+         * observed in the server differs from the one observed by end users,
+         * for example, when using a load balancer to offload TLS.
+         *
+         * Note that this configuration option does not allow setting a path as
+         * part of the URL. If your setup involves URL rewriting or any other
+         * tricks that would result in SimpleSAMLphp observing a URL for your
+         * application's scripts different than the canonical one, you will
+         * need to compute the right URLs yourself and pass them dynamically
+         * to SimpleSAMLphp's API.
+         */
+        //'baseURL' => 'https://example.com'
+    //),
+
     /*
      * The following settings are *filesystem paths* which define where
      * SimpleSAMLphp can find or write the following things:
diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php
index fd01223d7..624e8b505 100644
--- a/lib/SimpleSAML/Utils/HTTP.php
+++ b/lib/SimpleSAML/Utils/HTTP.php
@@ -778,15 +778,26 @@ class HTTP
              *   directory of SimpleSAMLphp, the URI does not contain its relative path, and $uri_pos is false.
              *
              * It doesn't matter which one of those cases we have. We just know we can't apply our base URL to the
-             * current URI, so we need to build it back from the PHP environment.
+             * current URI, so we need to build it back from the PHP environment, unless we have a base URL specified
+             * for this case in the configuration. First, check if that's the case.
              */
-            $protocol = 'http';
-            $protocol .= (self::getServerHTTPS()) ? 's' : '';
-            $protocol .= '://';
 
-            $hostname = self::getServerHost();
-            $port = self::getServerPort();
-            return $protocol.$hostname.$port.$_SERVER['REQUEST_URI'];
+            /** @var \SimpleSAML_Configuration $appcfg */
+            $appcfg = $cfg->getConfigItem('application', array());
+            $appurl = $appcfg->getString('baseURL', '');
+            if (!empty($appurl)) {
+                $protocol = parse_url($appurl, PHP_URL_SCHEME);
+                $hostname = parse_url($appurl, PHP_URL_HOST);
+                $port = parse_url($appurl, PHP_URL_PORT);
+                $port = !empty($port) ? ':'.$port : '';
+
+            } else { // no base URL specified for app, just use the current URL
+                $protocol = 'http';
+                $protocol .= (self::getServerHTTPS()) ? 's' : '';
+                $hostname = self::getServerHost();
+                $port = self::getServerPort();
+            }
+            return $protocol.'://'.$hostname.$port.$_SERVER['REQUEST_URI'];
         }
 
         return self::getBaseURL().$rel_path.substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path));
-- 
GitLab