summaryrefslogtreecommitdiffstats
path: root/inc/simplesamlphp/modules/authfacebook/lib/Facebook.php
diff options
context:
space:
mode:
Diffstat (limited to 'inc/simplesamlphp/modules/authfacebook/lib/Facebook.php')
-rw-r--r--inc/simplesamlphp/modules/authfacebook/lib/Facebook.php80
1 files changed, 72 insertions, 8 deletions
diff --git a/inc/simplesamlphp/modules/authfacebook/lib/Facebook.php b/inc/simplesamlphp/modules/authfacebook/lib/Facebook.php
index 7fc2ba5..04d47e2 100644
--- a/inc/simplesamlphp/modules/authfacebook/lib/Facebook.php
+++ b/inc/simplesamlphp/modules/authfacebook/lib/Facebook.php
@@ -8,6 +8,14 @@ require_once(dirname(dirname(__FILE__)) . '/extlibinc/base_facebook.php');
*/
class sspmod_authfacebook_Facebook extends BaseFacebook
{
+ const FBSS_COOKIE_NAME = 'fbss';
+
+ // We can set this to a high number because the main session
+ // expiration will trump this.
+ const FBSS_COOKIE_EXPIRE = 31556926; // 1 year
+
+ // Stores the shared session ID if one is set.
+ protected $sharedSessionID;
/* SimpleSAMLPhp state array */
protected $ssp_state;
@@ -18,18 +26,60 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
* access token if during the course of execution
* we discover them.
*
- * @param Array $config the application configuration.
+ * @param Array $config the application configuration. Additionally
+ * accepts "sharedSession" as a boolean to turn on a secondary
+ * cookie for environments with a shared session (that is, your app
+ * shares the domain with other apps).
* @see BaseFacebook::__construct in base_facebook.php
*/
public function __construct(array $config, &$ssp_state) {
$this->ssp_state = &$ssp_state;
parent::__construct($config);
+ if (!empty($config['sharedSession'])) {
+ $this->initSharedSession();
+ }
}
protected static $kSupportedKeys =
array('state', 'code', 'access_token', 'user_id');
+ protected function initSharedSession() {
+ $cookie_name = $this->getSharedSessionCookieName();
+ if (isset($_COOKIE[$cookie_name])) {
+ $data = $this->parseSignedRequest($_COOKIE[$cookie_name]);
+ if ($data && !empty($data['domain']) &&
+ self::isAllowedDomain($this->getHttpHost(), $data['domain'])) {
+ // good case
+ $this->sharedSessionID = $data['id'];
+ return;
+ }
+ // ignoring potentially unreachable data
+ }
+ // evil/corrupt/missing case
+ $base_domain = $this->getBaseDomain();
+ $this->sharedSessionID = md5(uniqid(mt_rand(), true));
+ $cookie_value = $this->makeSignedRequest(
+ array(
+ 'domain' => $base_domain,
+ 'id' => $this->sharedSessionID,
+ )
+ );
+ $_COOKIE[$cookie_name] = $cookie_value;
+ if (!headers_sent()) {
+ $expire = time() + self::FBSS_COOKIE_EXPIRE;
+ setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain);
+ } else {
+ // @codeCoverageIgnoreStart
+ SimpleSAML_Logger::debug(
+ 'Shared session ID cookie could not be set! You must ensure you '.
+ 'create the Facebook instance before headers have been sent. This '.
+ 'will cause authentication issues after the first request.'
+ );
+ // @codeCoverageIgnoreEnd
+ }
+ }
+
/**
* Provides the implementations of the inherited abstract
* methods. The implementation uses PHP sessions to maintain
@@ -53,10 +103,8 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
}
$session_var_name = $this->constructSessionVariableName($key);
- if (isset($this->ssp_state[$session_var_name])) {
- $value = $this->ssp_state[$session_var_name];
- }
- return isset($value) ? $value : $default;
+ return isset($this->ssp_state[$session_var_name]) ?
+ $this->ssp_state[$session_var_name] : $default;
}
protected function clearPersistentData($key) {
@@ -75,11 +123,27 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
foreach (self::$kSupportedKeys as $key) {
$this->clearPersistentData($key);
}
+ if ($this->sharedSessionID) {
+ $this->deleteSharedSessionCookie();
+ }
+ }
+
+ protected function deleteSharedSessionCookie() {
+ $cookie_name = $this->getSharedSessionCookieName();
+ unset($_COOKIE[$cookie_name]);
+ $base_domain = $this->getBaseDomain();
+ setcookie($cookie_name, '', 1, '/', '.'.$base_domain);
+ }
+
+ protected function getSharedSessionCookieName() {
+ return self::FBSS_COOKIE_NAME . '_' . $this->getAppId();
}
protected function constructSessionVariableName($key) {
- return 'authfacebook:authdata:' . implode('_', array('fb',
- $this->getAppId(),
- $key));
+ $parts = array('authfacebook:authdata:fb', $this->getAppId(), $key);
+ if ($this->sharedSessionID) {
+ array_unshift($parts, $this->sharedSessionID);
+ }
+ return implode('_', $parts);
}
}