contao/core — pull request #6831 by redneck-ebfe (2014-03-27 14:34:06+00:00)
Title: Revise algorithm to get "proxied" Client-IP

I am working on a single-sign-on with other applications where Contao is the master. This depends on a correct handling of the X-Forwarded-For header.

To validate the Session, I send a http-sub-request to Contao with the cookies received from the client. Now, Contao validates the session and sends back the session cookies. These cookies from the sub-request were forwarded to the client. This is the same as sending the request through a proxy.

With the current implementation this only works with ```$GLOBALS['TL_CONFIG']['disableIpCheck'] = true;``` (and at localhost).

On Contao-side I have the following code in ``./share/sso_username.php`` which just prints the username and sends the cookies.
```php
import('FrontendUser', 'User');
parent::__construct();
define('BE_USER_LOGGED_IN', $this->getLoginStatus('BE_USER_AUTH'));
define('FE_USER_LOGGED_IN', $this->getLoginStatus('FE_USER_AUTH'));
}
public function run()
{
$this->User->authenticate();
header('Content-Type: text/plain');
echo $this->User->username;
}
}

(new SsoUsername())->run();
```

On the other side (in this case phpBB3) my authentication plugin has the following function to get Contaos frontend-user.
```php
define('SSO_USERNAME_URL', 'http://localhost/share/sso_username.php');

/**
* Get the username of current Contao session and forward Cookies from sub-request to the client.
*
* @return username of current Contao session
*/
function get_current_user_contao() {
static $user_contao = false;

// Do it once per request
if ($user_contao !== false) {
return $user_contao;
}

// Create context for sub-request, append remote address to XFF-Header
$ctx = stream_context_create(array(
'http'=>array(
'method'=>"GET",
'protocol_version'=>0.9,
'header'=>
'X-Forwarded-For: ' . (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? "${_SERVER['HTTP_X_FORWARDED_FOR']}, " :'') . "${_SERVER['REMOTE_ADDR']}\r\n" .
"Cookie: ${_SERVER['HTTP_COOKIE']}\r\n"
)
));

// request the username
$user_contao = file_get_contents(SSO_USERNAME_URL, false, $ctx);

// forward cookies
foreach ($http_response_header as $h) {
list($k, $v) = explode(':', $h, 2);
if (strtolower($k) === 'set-cookie') {
header($h, false);
}
}

// return username
return $user_contao;
}
```