diff --git a/config-templates/config.php b/config-templates/config.php
index 97ae7b7c9784a20c100650735fd61c13a3110ec0..33915d604e4c000d1bd7ff229e49259057829ab3 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -10,6 +10,17 @@ $config = array (
 	/**
 	 * Setup the following parameters to match the directory of your installation.
 	 * See the user manual for more details.
+	 *
+	 * Valid format for baseurlpath is:
+	 * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]
+	 * (note that it must end with a '/')
+	 *
+	 * The full url format is useful if your simpleSAMLphp setup is hosted behind
+	 * a reverse proxy. In that case you can specify the external url here.
+	 *
+	 * Please note that simpleSAMLphp will then redirect all queries to the
+	 * external url, no matter where you come from (direct access or via the
+	 * reverse proxy).
 	 */
 	'baseurlpath'           => 'simplesaml/',
 	'certdir'               => 'cert/',
diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index f0d1ece8ab80856caa9802b65a1f55e8f7293d28..ac86d2d3ffbbb587757a1318550780f544d94d29 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -337,14 +337,36 @@ class SimpleSAML_Configuration {
 		return FALSE;
 	}
 
-	
-	
+	/**
+	 * Retrieve the absolute path of the simpleSAMLphp installation,
+	 * relative to the root of the website.
+	 *
+	 * For example: simplesaml/
+	 *
+	 * The path will always end with a '/' and never have a leading slash.
+	 *
+	 * @return string  The absolute path relative to the root of the website.
+	 */
 	public function getBaseURL() {
-		if (preg_match('/^\*(.*)$/D', $this->getString('baseurlpath', 'simplesaml/'), $matches)) {
+		$baseURL = $this->getString('baseurlpath', 'simplesaml/');
+		
+		if (preg_match('/^\*(.*)$/D', $baseURL, $matches)) {
+			/* deprecated behaviour, will be removed in the future */
 			return SimpleSAML_Utilities::getFirstPathElement(false) . $matches[1];
 		}
 
-		return $this->getString('baseurlpath', 'simplesaml/');
+		if (preg_match('#^https?://[^/]*/(.*)$#', $baseURL, $matches)) {
+			/* we have a full url, we need to strip the path */
+			return $matches[1];
+		} elseif (preg_match('#^/?([^/]?.*/)#D', $baseURL, $matches)) {
+			/* local path only */
+			return $matches[1];
+		} else {
+			/* invalid format */
+			throw new SimpleSAML_Error_Exception('Incorrect format for option \'baseurlpath\'. Value is: "'.
+				$this->getString('baseurlpath', 'simplesaml/') . '". Valid format is in the form'.
+				' [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/].');
+		}
 	}
 
 
diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index e0feecd4005a4c69ce353bfe48d366e14cbc12a2..c522d120767d537ecbd1b1507a737b68d0b0e7bf 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -33,7 +33,21 @@ class SimpleSAML_Utilities {
 	 * Will return sp.example.org
 	 */
 	public static function getSelfHost() {
+
+		$url = self::getBaseURL();
+
+		$start = strpos($url,'://') + 3;
+		$length = strcspn($url,'/:',$start);
+
+		return substr($url, $start, $length);
+
+	}
 	
+	/**
+	 * Retrieve Host value from $_SERVER environment variables
+	 */
+	private static function getServerHost() {
+
 		if (array_key_exists('HTTP_HOST', $_SERVER)) {
 			$currenthost = $_SERVER['HTTP_HOST'];
 		} elseif (array_key_exists('SERVER_NAME', $_SERVER)) {
@@ -47,7 +61,8 @@ class SimpleSAML_Utilities {
 				$currenthostdecomposed = explode(":", $currenthost);
 				$currenthost = $currenthostdecomposed[0];
 		}
-		return $currenthost;# . self::getFirstPathElement() ;
+		return $currenthost;
+
 	}
 
 
@@ -55,27 +70,15 @@ class SimpleSAML_Utilities {
 	 * Will return https://sp.example.org
 	 */
 	public static function selfURLhost() {
-	
-		$currenthost = self::getSelfHost();
 
-		if (SimpleSAML_Utilities::isHTTPS()) {
-			$protocol = 'https';
-		} else {
-			$protocol = 'http';
-		}
-		
-		$portnumber = $_SERVER["SERVER_PORT"];
-		$port = ':' . $portnumber;
-		if ($protocol == 'http') {
-			if ($portnumber == '80') $port = '';
-		} elseif ($protocol == 'https') {
-			if ($portnumber == '443') $port = '';
-		}
-			
-		$querystring = '';
-		return $protocol."://" . $currenthost . $port;
-	
+		$url = self::getBaseURL();
+
+		$start = strpos($url,'://') + 3;
+		$length = strcspn($url,'/:',$start) + $start;
+
+		return substr($url, 0, $length);
 	}
+
 	
 	/**
 	 * This function checks if we should set a secure cookie.
@@ -84,8 +87,26 @@ class SimpleSAML_Utilities {
 	 */
 	public static function isHTTPS() {
 
+		$url = self::getBaseURL();
+
+		$end = strpos($url,'://');
+		$protocol = substr($url, 0, $end);
+
+		if ($protocol === 'https') {
+			return TRUE;
+		} else {
+			return FALSE;
+		}
+
+	}
+
+	/**
+	 * retrieve HTTPS status from $_SERVER environment variables
+	 */
+	private static function getServerHTTPS() {
+
 		if(!array_key_exists('HTTPS', $_SERVER)) {
-			/* Not a https-request. */
+			/* Not an https-request. */
 			return FALSE;
 		}
 
@@ -96,8 +117,30 @@ class SimpleSAML_Utilities {
 
 		/* Otherwise, HTTPS will be a non-empty string. */
 		return $_SERVER['HTTPS'] !== '';
+
 	}
-	
+
+
+	/**
+	 * Retrieve port number from $_SERVER environment variables
+	 * return it as a string such as ":80" if different from
+	 * protocol default port, otherwise returns an empty string
+	 */
+	private static function getServerPort() {
+
+		$portnumber = $_SERVER["SERVER_PORT"];
+		$port = ':' . $portnumber;
+
+		if (self::getServerHTTPS()) {
+			if ($portnumber == '443') $port = '';
+		} else {
+			if ($portnumber == '80') $port = '';
+		}
+
+		return $port;
+
+	}
+
 	/**
 	 * Will return https://sp.example.org/universities/ruc/baz/simplesaml/saml2/SSOService.php
 	 */
@@ -139,6 +182,7 @@ class SimpleSAML_Utilities {
 	
 
 	public static function selfURL() {
+
 		$selfURLhost = self::selfURLhost();
 
 		$requestURI = $_SERVER['REQUEST_URI'];
@@ -150,14 +194,14 @@ class SimpleSAML_Utilities {
 		}
 
 		return $selfURLhost . $requestURI;
+
 	}
 
 
 	/**
-	 * Retrieve the absolute base URL for the simpleSAMLphp installation.
+	 * Retrieve and return the absolute base URL for the simpleSAMLphp installation.
 	 *
-	 * This function will return the absolute base URL for the simpleSAMLphp
-	 * installation. For example: https://idp.example.org/simplesaml/
+	 * For example: https://idp.example.org/simplesaml/
 	 *
 	 * The URL will always end with a '/'.
 	 *
@@ -166,13 +210,35 @@ class SimpleSAML_Utilities {
 	public static function getBaseURL() {
 
 		$globalConfig = SimpleSAML_Configuration::getInstance();
-		$ret = SimpleSAML_Utilities::selfURLhost() . '/' . $globalConfig->getBaseURL();
-		if (substr($ret, -1) !== '/') {
-			throw new SimpleSAML_Error_Exception('Invalid value of \'baseurl\' in ' .
-				'config.php. It must end with a \'/\'.');
+		$baseURL = $globalConfig->getString('baseurlpath', 'simplesaml/');
+		
+		if (preg_match('#^https?://([^/]*)/(.*)/$#D', $baseURL, $matches)) {
+			/* full url in baseurlpath, override local server values */
+			return $baseURL;
+		} elseif (
+			(preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) ||
+			(preg_match('#^\*(.*)/$#D', $baseURL, $matches))) {
+			/* get server values */
+
+			if (self::getServerHTTPS()) {
+				$protocol = 'https://';
+			} else {
+				$protocol = 'http://';
+			}
+
+			$hostname = self::getServerHost();
+			$port = self::getServerPort();
+			$path = $globalConfig->getBaseURL();
+			if ($path[0] != '/') $path = '/' . $path;
+
+			return $protocol.$hostname.$port.$path;
+		} else {
+			throw new SimpleSAML_Error_Exception('Invalid value of \'baseurl\' in '.
+				'config.php. Valid format is in the form: '.
+				'[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. '.
+				'It must end with a \'/\'.');
 		}
 
-		return $ret;
 	}