Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions settings_example.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
// Ex. http://sp.example.com/
// http://example.com/sp/
'baseurl' => null,

// Set a base path to the application on the server or local virtual host.
// Could be used when behin a proxy, in the view that process the SAML Message.
// Ex. /my/local/installation/directory/
'localUrlPath' => null,

// If 'useProxy' is true, some Utils methods will take care of the
// $_SERVER["HTTP_X_FORWARDED_PORT"] and $_SERVER['HTTP_X_FORWARDED_PROTO']
// vars (otherwise they are ignored).
'useProxy' => false,

// Service Provider Data that we are deploying
'sp' => array(
Expand Down
3 changes: 3 additions & 0 deletions src/Saml2/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ class Auth
public function __construct(?array $settings = null, bool $spValidationOnly = false)
{
$this->_settings = new Settings($settings, $spValidationOnly);
if ($this->_settings->proxyUsage()){
Utils::setProxyUsage(true);
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/Saml2/LogoutRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,19 @@ public function __construct(\OneLogin\Saml2\Settings $settings, $request = null,
{
$this->_settings = $settings;

if ($this->_settings->proxyUsage()){
Utils::setProxyUsage(true);
}

$baseURL = $this->_settings->getBaseURL();
if (!empty($baseURL)) {
Utils::setBaseURL($baseURL);
}

$localURLPath = $this->_settings->getLocalURLPath();
if (!empty($localURLPath)) {
Utils::setLocalURLPath($localURLPath);
}

if (!isset($request) || empty($request)) {
$spData = $this->_settings->getSPData();
Expand Down
9 changes: 9 additions & 0 deletions src/Saml2/LogoutResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,19 @@ public function __construct(\OneLogin\Saml2\Settings $settings, $response = null
{
$this->_settings = $settings;

if ($this->_settings->proxyUsage()){
Utils::setProxyUsage(true);
}

$baseURL = $this->_settings->getBaseURL();
if (!empty($baseURL)) {
Utils::setBaseURL($baseURL);
}

$localURLPath = $this->_settings->getLocalURLPath();
if (!empty($localURLPath)) {
Utils::setLocalURLPath($localURLPath);
}

if ($response) {
$decoded = base64_decode($response);
Expand Down
9 changes: 9 additions & 0 deletions src/Saml2/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,20 @@ class Response
public function __construct(\OneLogin\Saml2\Settings $settings, $response)
{
$this->_settings = $settings;

if ($this->_settings->proxyUsage()){
Utils::setProxyUsage(true);
}

$baseURL = $this->_settings->getBaseURL();
if (!empty($baseURL)) {
Utils::setBaseURL($baseURL);
}

$localURLPath = $this->_settings->getLocalURLPath();
if (!empty($localURLPath)) {
Utils::setLocalURLPath($localURLPath);
}

$this->response = base64_decode($response);

Expand Down
52 changes: 50 additions & 2 deletions src/Saml2/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,19 @@ class Settings
* @var string
*/
private $_baseurl;



/**
* @var string
*/
private $_localUrlPath;


/**
* @var bool
*/
private $_useProxy = false;

/**
* Strict. If active, PHP Toolkit will reject unsigned or unencrypted messages
* if it expects them signed or encrypted. If not, the messages will be accepted
Expand Down Expand Up @@ -261,10 +273,16 @@ private function _loadSettingsFromArray(array $settings)
if (isset($settings['debug'])) {
$this->_debug = $settings['debug'];
}

if (isset($settings['useProxy'])) {
$this->_useProxy = $settings['useProxy'];
}
if (isset($settings['baseurl'])) {
$this->_baseurl = $settings['baseurl'];
}

if (isset($settings['localUrlPath'])) {
$this->_localUrlPath = $settings['localUrlPath'];
}

if (isset($settings['compress'])) {
$this->_compress = $settings['compress'];
Expand Down Expand Up @@ -1131,6 +1149,16 @@ public function isDebugActive()
{
return $this->_debug;
}

/**
* Returns if the app is behind a reverse proxy.
*
* @return bool Proxy usage parameter
*/
public function proxyUsage()
{
return $this->_useProxy;
}

/**
* Set a baseurl value.
Expand All @@ -1151,6 +1179,26 @@ public function getBaseURL()
{
return $this->_baseurl;
}

/**
* Set a baseurl value.
*
* @param string $baseurl Base URL.
*/
public function setLocalURLPath($localurlpath)
{
$this->_localUrlPath = $localurlpath;
}

/**
* Returns the localUrlPath set on the settings if any.
*
* @return null|string The localUrlPath
*/
public function getLocalURLPath()
{
return $this->_localUrlPath;
}

/**
* Sets the IdP certificate.
Expand Down
133 changes: 101 additions & 32 deletions src/Saml2/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Utils
/**
* @var bool Control if the `Forwarded-For-*` headers are used
*/
private static $_proxyVars = false;
private static $_proxyUsage = false;

/**
* @var string|null
Expand All @@ -63,6 +63,11 @@ class Utils
* @var string|null
*/
private static $_baseurlpath;

/**
* @var string|null
*/
private static $_localpath;

/**
* This function load an XML string in a save way.
Expand Down Expand Up @@ -430,20 +435,63 @@ public static function setBaseURL($baseurl)
}
}

/**
* Set the local path value.
*
* @param string $path The path of base path of application on server
*/
public static function setLocalURLPath($path)
{
if (empty($path)) {
self::$_localpath = null;
} else if ($path == '/') {
self::$_localpath = '/';
} else {
self::$_localpath = '/' . trim($path, '/') . '/';
}
}

/**
* @return string The local path to be used when constructing URLs
*/
public static function getLocalURLPath()
{
return self::$_localpath;
}


/**
* @param bool $proxyUsage Whether to use `X-Forwarded-*` headers to determine port/domain/protocol
*/
public static function setProxyUsage($proxyUsage)
{
self::$_proxyUsage = (bool)$proxyUsage;
}

/**
* @return bool
*/
public static function getProxyUsage()
{
return self::$_proxyUsage;
}

/**
* For retro-compatibility
* @param bool $proxyVars Whether to use `X-Forwarded-*` headers to determine port/domain/protocol
*/
public static function setProxyVars($proxyVars)
{
self::$_proxyVars = (bool)$proxyVars;
self::setProxyUsage($proxyVars);
}

/**
* For retro-compatibility
* @return bool
*/
public static function getProxyVars()
{
return self::$_proxyVars;
return self::getProxyUsage();
}

/**
Expand Down Expand Up @@ -621,14 +669,12 @@ public static function isHTTPS()
public static function getSelfURLNoQuery()
{
$selfURLNoQuery = self::getSelfURLhost();

$infoWithBaseURLPath = self::buildWithBaseURLPath($_SERVER['SCRIPT_NAME']);
if (!empty($infoWithBaseURLPath)) {
$selfURLNoQuery .= $infoWithBaseURLPath;
} else {
$selfURLNoQuery .= $_SERVER['SCRIPT_NAME'];
}


$route = self::shiftLocalURLPath($_SERVER['SCRIPT_NAME']);
$route = self::buildWithBaseURLPath($route);

$selfURLNoQuery .= $route;

if (isset($_SERVER['PATH_INFO'])) {
$selfURLNoQuery .= $_SERVER['PATH_INFO'];
}
Expand All @@ -645,22 +691,17 @@ public static function getSelfRoutedURLNoQuery()
{
$selfURLhost = self::getSelfURLhost();
$route = '';

if (!empty($_SERVER['REQUEST_URI'])) {
$route = $_SERVER['REQUEST_URI'];
if (!empty($_SERVER['QUERY_STRING'])) {
$route = self::strLreplace($_SERVER['QUERY_STRING'], '', $route);
if (substr($route, -1) == '?') {
$route = substr($route, 0, -1);
}
}
$route = self::truncateQueryString($route);
$route = self::shiftLocalURLPath($route);
}

$infoWithBaseURLPath = self::buildWithBaseURLPath($route);
if (!empty($infoWithBaseURLPath)) {
$route = $infoWithBaseURLPath;
}

$selfRoutedURLNoQuery = $selfURLhost . $route;

$pos = strpos($selfRoutedURLNoQuery, "?");
Expand All @@ -671,14 +712,17 @@ public static function getSelfRoutedURLNoQuery()
return $selfRoutedURLNoQuery;
}

public static function strLreplace($search, $replace, $subject)
public static function truncateQueryString($subject)
{
$pos = strrpos($subject, $search);

if ($pos !== false) {
$subject = substr_replace($subject, $replace, $pos, strlen($search));
if (!empty($_SERVER['QUERY_STRING'])) {
$pos = strrpos($subject, $_SERVER['QUERY_STRING']);
if ($pos !== false) {
$subject = substr_replace($subject, '', $pos, strlen($_SERVER['QUERY_STRING']));
}
}
if (substr($subject, -1) == '?') {
$subject = substr($subject, 0, -1);
}

return $subject;
}

Expand All @@ -691,20 +735,17 @@ public static function getSelfURL()
{
$selfURLhost = self::getSelfURLhost();

$requestURI = '';
$requestURI = '';
if (!empty($_SERVER['REQUEST_URI'])) {
$requestURI = $_SERVER['REQUEST_URI'];
$matches = array();
if ($requestURI[0] !== '/' && preg_match('#^https?://[^/]*(/.*)#i', $requestURI, $matches)) {
$requestURI = $matches[1];
}
$requestURI = self::shiftLocalURLPath($requestURI);
}

$infoWithBaseURLPath = self::buildWithBaseURLPath($requestURI);
if (!empty($infoWithBaseURLPath)) {
$requestURI = $infoWithBaseURLPath;
}

return $selfURLhost . $requestURI;
}

Expand Down Expand Up @@ -736,6 +777,34 @@ protected static function buildWithBaseURLPath($info)
}
return $result;
}

/**
* Returns the part of the URL without the localPath.
*
* @param string $info Contains path info
*
* @return string
*/
protected static function shiftLocalURLPath($info)
{
$result = '/';
if (!empty($info)) {
$localURLPath = self::getLocalURLPath();
if (!empty($localURLPath)) {
$extractedInfo = $info;
if ($localURLPath != '/') {
// Remove base path from the path info.
$extractedInfo = str_replace($localURLPath, '', $info);
}
// Remove starting and ending slash.
$extractedInfo = trim($extractedInfo, '/');
if (!empty($extractedInfo)) {
$result .= $extractedInfo;
}
}
}
return $result;
}

/**
* Extract a query param - as it was sent - from $_SERVER[QUERY_STRING]
Expand Down