Skip to content

Commit

Permalink
Don't use cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
RoSk0 committed Oct 29, 2023
1 parent 71cb642 commit 056aec6
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 136 deletions.
10 changes: 0 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,6 @@ Configure the authentication source by putting following code into `simplesamlph
// Whether to turn on debug
'debug' => true,

// Cookie name. Set this to use a cache-busting cookie pattern
// (e.g. 'SESSdrupalauth4ssp') if hosted on Pantheon so that the cookie
// is is not stripped away by Varnish. See https://pantheon.io/docs/cookies#cache-busting-cookies .
'cookie_name' => 'drupalauth4ssp',

// Which attributes should be retrieved from the Drupal site.
'attributes' => array(
array('field_name' => 'uid', 'attribute_name' => 'uid'),
Expand Down Expand Up @@ -108,11 +103,6 @@ Configure the authentication source by putting following code into `simplesamlph
// Whether to turn on debug
'debug' => true,

// Cookie name. Set this to use a cache-busting cookie pattern
// (e.g. 'SESSdrupalauth4ssp') if hosted on Pantheon so that the cookie
// is is not stripped away by Varnish. See https://pantheon.io/docs/cookies#cache-busting-cookies .
'cookie_name' => 'drupalauth4ssp',

// the URL of the Drupal logout page
'drupal_logout_url' => 'https://www.example.com/drupal/user/logout',

Expand Down
97 changes: 36 additions & 61 deletions lib/Auth/Source/External.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@
* // Whether to turn on debug
* 'debug' => true,
*
* // Cookie name.
* 'cookie_name' => 'drupalauth4ssp'
*
* // URL of the Drupal logout page.
* 'drupal_logout_url' => 'https://www.example.com/drupal7/user/logout',
*
Expand Down Expand Up @@ -78,7 +75,22 @@
class External extends Source
{

/**
/**
* The string used to identify Drupal user ID.
*/
const DRUPALAUTH_EXTERNAL_USER_ID = 'drupalauth:External:UserID';

/**
* The string used to identify authentication source.
*/
const DRUPALAUTH_AUTH_ID = 'drupalauth:AuthID';

/**
* The string used to identify our states.
*/
const DRUPALAUTH_EXTERNAL = 'drupalauth:External';

/**
* Configuration object.
*
* @var \SimpleSAML\Module\drupalauth\ConfigHelper
Expand Down Expand Up @@ -114,46 +126,14 @@ public function __construct($info, $config)
*
* @return array|NULL The user's attributes, or NULL if the user isn't authenticated.
*/
private function getUser()
private function getUser($drupaluid)
{

$drupaluid = null;

// Pull the Drupal UID out of the cookie.
$cookie_name = $this->config->getCookieName();
if (isset($_COOKIE[$cookie_name]) && $_COOKIE[$cookie_name]) {
$strCookie = $_COOKIE[$cookie_name];
list($cookie_hash, $uid) = explode(':', $strCookie);

// make sure the hash matches
// make sure the UID is passed
if ((isset($cookie_hash) && !empty($cookie_hash)) && (isset($uid) && !empty($uid))) {
$drupalHelper = new DrupalHelper();
$drupalHelper->bootDrupal($this->config->getDrupalroot());

// Make sure no one manipulated the hash or the uid in the cookie before we trust the uid
$hash = Crypt::hmacBase64(
$uid,
$this->config->getCookieSalt() . \Drupal::service('private_key')->get()
);
if (!hash_equals($hash, $cookie_hash)) {
throw new Exception(
'Cookie hash invalid. This indicates either tampering or an out of date drupal4ssp module.'
);
}
$drupaluid = $uid;
}
}


// Delete the cookie, we don't need it anymore
if (isset($_COOKIE[$cookie_name])) {
setcookie($cookie_name, "", time() - 3600, $this->config->getCookiePath());
}

if (!empty($drupaluid)) {
// Load the user object from Drupal.
$drupaluser = User::load($uid);
$drupalHelper = new DrupalHelper();
$drupalHelper->bootDrupal($this->config->getDrupalroot());

// Load the user object from Drupal.
$drupaluser = User::load($drupaluid);
if ($drupaluser->isBlocked()) {
throw new Error('NOACCESS');
}
Expand All @@ -173,7 +153,7 @@ public function authenticate(&$state)
{
assert(is_array($state));

$attributes = $this->getUser();
$attributes = $this->getUser($state[self::DRUPALAUTH_EXTERNAL_USER_ID]);
if ($attributes !== null) {
/*
* The user is already authenticated.
Expand All @@ -194,7 +174,7 @@ public function authenticate(&$state)
* First we add the identifier of this authentication source
* to the state array, so that we know where to resume.
*/
$state['drupalauth:AuthID'] = $this->getAuthId();
$state[self::DRUPALAUTH_AUTH_ID] = $this->getAuthId();

/*
* We need to save the $state-array, so that we can resume the
Expand All @@ -209,7 +189,7 @@ public function authenticate(&$state)
* and restores it in another location, and thus bypasses steps in
* the authentication process.
*/
$stateId = State::saveState($state, 'drupalauth:External');
$stateId = State::saveState($state, self::DRUPALAUTH_EXTERNAL);

/*
* Now we generate a URL the user should return to after authentication.
Expand Down Expand Up @@ -253,33 +233,33 @@ public function authenticate(&$state)
*
* @param array &$state The authentication state.
*/
public static function resume()
public static function resume($stateID)
{
/*
* First we need to restore the $state-array. We should have the identifier for
* it in the 'State' request parameter.
*/
if (!isset($_REQUEST['State'])) {
if (!isset($stateID)) {
throw new BadRequest('Missing "State" parameter.');
}

/*
* Once again, note the second parameter to the loadState function. This must
* match the string we used in the saveState-call above.
*/
$state = State::loadState($_REQUEST['State'], 'drupalauth:External');
$state = State::loadState($stateID, self::DRUPALAUTH_EXTERNAL);

/*
* Now we have the $state-array, and can use it to locate the authentication
* source.
*/
$source = Source::getById($state['drupalauth:AuthID']);
$source = Source::getById($state[self::DRUPALAUTH_AUTH_ID]);
if ($source === null) {
/*
* The only way this should fail is if we remove or rename the authentication source
* while the user is at the login page.
*/
throw new Exception('Could not find authentication source with ID: ' . $state['drupalauth:AuthID']);
throw new Exception('Could not find authentication source with ID: ' . $state[self::DRUPALAUTH_AUTH_ID]);
}

/*
Expand All @@ -291,12 +271,12 @@ public static function resume()
throw new Exception('Authentication source type changed.');
}

/*
* OK, now we know that our current state is sane. Time to actually log the user in.
*
* First we check that the user is acutally logged in, and didn't simply skip the login page.
*/
$attributes = $source->getUser();
/*
* OK, now we know that our current state is sane. Time to actually log the user in.
*
* First we check that the user is acutally logged in, and didn't simply skip the login page.
*/
$attributes = $source->getUser($state[self::DRUPALAUTH_EXTERNAL_USER_ID]);
if ($attributes === null) {
/*
* The user isn't authenticated.
Expand Down Expand Up @@ -336,11 +316,6 @@ public function logout(&$state)
session_start();
}

// Added armor plating, just in case.
if (isset($_COOKIE[$this->config->getCookieName()])) {
setcookie($this->config->getCookieName(), "", time() - 3600, $this->config->getCookiePath());
}

$logout_url = $this->config->getDrupalLogoutURL();
$parameters = [];
if (!empty($state['ReturnTo'])) {
Expand Down
75 changes: 11 additions & 64 deletions lib/ConfigHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,6 @@ class ConfigHelper
private $attributes;


/**
* The name of the cookie
*/
private $cookie_name;


/**
* Cookie path.
*/
private $cookie_path;


/**
* Cookie salt.
*/
private $cookie_salt;


/**
* The Drupal logout URL
*/
Expand All @@ -75,28 +57,22 @@ class ConfigHelper
* @param array $config Configuration.
* @param string $location The location of this configuration. Used for error reporting.
*/
public function __construct($config, $location)
{
assert(is_array($config));
assert(is_string($location));

$this->location = $location;
public function __construct($config, $location) {
assert(is_array($config));
assert(is_string($location));

/* Get authsource configuration. */
$config = Configuration::loadFromArray($config, $location);
$this->location = $location;

$this->drupalroot = $config->getString('drupalroot');
$this->debug = $config->getBoolean('debug', false);
$this->attributes = $config->getArray('attributes', []);
$this->cookie_name = $config->getString('cookie_name', 'drupalauth4ssp');
$this->drupal_logout_url = $config->getString('drupal_logout_url', null);
$this->drupal_login_url = $config->getString('drupal_login_url', null);
/* Get authsource configuration. */
$config = Configuration::loadFromArray($config, $location);

$this->cookie_path = Configuration::getInstance()->getBasePath();
$this->cookie_salt = Config::getSecretSalt();
$this->drupalroot = $config->getString('drupalroot');
$this->debug = $config->getBoolean('debug', FALSE);
$this->attributes = $config->getArray('attributes', []);
$this->drupal_logout_url = $config->getString('drupal_logout_url', NULL);
$this->drupal_login_url = $config->getString('drupal_login_url', NULL);
}


/**
* Returns debug mode.
*
Expand Down Expand Up @@ -127,35 +103,6 @@ public function getAttributes()
return $this->attributes;
}

/**
* Returns cookie name.
*
* @return string
*/
public function getCookieName()
{
return $this->cookie_name;
}

/**
* Returns cookie path.
*
* @return string
*/
public function getCookiePath()
{
return $this->cookie_path;
}

/**
* Returns cookie salt.
*
* @return string
*/
public function getCookieSalt()
{
return $this->cookie_salt;
}

/**
* Returns Drupal logout URL.
Expand Down
2 changes: 1 addition & 1 deletion www/resume.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

use SimpleSAML\Module\drupalauth\Auth\Source\External;

External::resume();
External::resume($_REQUEST['State']);

0 comments on commit 056aec6

Please sign in to comment.