We had previously defined all environments to use a wildcard domain like .example.org for all SimpleSAMLPHP cookies. This caused all the environments under the same domain to have overlapping SSO logins, which often broke the login altogether for users using the test environments.
We decided to fix this, but as this changed the cookie domains for all environments it also broke the logins. Here's a pretty simple solution to remove the old cookies from the user's browsers before they get in the login flow using the Drupal module. The idea here is to not have to patch or edit SimpleSAMLPHP but still do this in a fairly simple and performant way. This is likely a temporary fix that can be removed after a week or a few (once all the users have had their old cookies removed.)
First, add a service declaration to a module (or create a new one if you want) in mymodule.services.yml
:
services:
mymodule.route_subscriber:
class: Drupal\mymodule\Routing\RouteSubscriber
tags:
- { name: event_subscriber }
Then add the route subscriber to src/Routing/RouteSubscriber.php
:
<?php
namespace Drupal\mymodule\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Drupal\Core\Routing\RoutingEvents;
use Symfony\Component\Routing\RouteCollection;
/**
* Alter some routes.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* Alter some routes.
*/
public function alterRoutes(RouteCollection $collection) {
if ($route = $collection->get('simplesamlphp_auth.saml_login')) {
$route->setDefault('_controller', '\Drupal\mymodule\Controller\SimplesamlphpAuthControllerOverride::authenticate');
}
}
/**
* Subscribe to events.
*/
public static function getSubscribedEvents(): array {
$events = parent::getSubscribedEvents();
// Make sure we run after other modules.
$events[RoutingEvents::ALTER] = ['onAlterRoutes', 1];
return $events;
}
}
And then add the overriding controller to implement the actual cookie deletion in src/Controller/SimplesamlphpAuthControllerOverride.php
:
<?php
namespace Drupal\mymodule\Controller;
use Drupal\simplesamlphp_auth\Controller\SimplesamlphpAuthController;
/**
* Overriding controller to remove the old SAML cookie before auth.
*/
class SimplesamlphpAuthControllerOverride extends SimplesamlphpAuthController {
/**
* {@inheritdoc}
*/
public function authenticate() {
// Remove old cookie with incorrect domain.
setcookie('SimpleSAMLSessionID', '', 0, '/', '.example.org');
setcookie('SimpleSAMLAuthToken', '', 0, '/', '.example.org');
return parent::authenticate();
}
}