Les trois premières alternatives font l’objet de propositions de spécification émises en 2020. OAuthSD ne met en œuvre que OpenID Connect Session Management.
La troisième solution est plus ancienne et ne devrait pas l’emporter sur ces définitions plus récentes.
Quoiqu’il en soit, la solution de monitoring implémentée par OAuthSD fonctionne parfaitement et est extrêmement simple, ne nécessitant pas de modification du serveur. Elle a l’avantage de permettre également de signaler à l’utilisateur l’approche de la fin de la session OIDC et de lui offrir de la prolonger.
Nous ne sommes donc pas très motivés pour appliquer l’une ou l’autre de ces méthodes.
OpenID Connect Front-Channel Logout
Voir : OpenID Connect Front-Channel Logout 1.0 - draft 04 (août 2020).
OpenID Connect Back-Channel Logout
Voir : OpenID Connect Back-Channel Logout 1.0 - draft 06 (août 2020).
OpenID Connect Session Management
Nous avons décrit cette méthode ici : OpenID Connect Session Management. Son principe et sa complexité sont assez semblables aux deux précédentes.
OAuthSD met en œuvre cette méthode à des fins d’expérimentation et de suivi de la norme OpenID Connect.
Solution utilisée par Drupal et Google Accounts
Voir : https://www.drupal.org/project/openid_connect_sso
Après la connexion de l’utilisateur sur le serveur ou la déconnexion de l’un des sites du réseau, le module démarre une chaîne de redirection qui visite le script SSO de chaque site du réseau.
Le script SSO définit ensuite un cookie informant le site parent de la connexion/déconnexion en attente.
Lorsque l’utilisateur visite le site réel, le cookie est lu et l’utilisateur se connecte/déconnecte automatiquement.Cette approche est identique à celle utilisée par les comptes Google.
Le but des redirections est de donner à chaque site la possibilité de définir un cookie valide pour son domaine contournant ainsi la politique de même origine qui interdit à un site de définir un cookie pour un autre domaine.
Les redirections sont rapides et imperceptibles, car le script SSO est autonome ... et ne définit que le cookie.
- <?php
- /**
- * @file
- * Creates cookies for each of the network sites to signal a login/logout.
- */
- // Some pre-HTTP/1.1 clients will not send a Host header.
- // We can't work around this.
- exit;
- }
- // The collection of SSO script addresses which form the redirection network.
- // Don't include the protocol (http://, https://).
- // Example url (SSO script on subdomain): "a.firstsite.com"
- // Example url (SSO script in the Drupal directory): "firstsite.com/sso.php"
- 'a.firstsite.com',
- 'a.shop.secondsite.com',
- );
- // An array of network domain names. The keys are potential origin host names
- // which do not appear in the list above, and each value is the cookie domain
- // name for that host.
- // $domains = array();
- // Enable HTTPS for all redirect URLs.
- // $https = true;
- // Enable adding the domain name to the cookie name.
- // $cookie_name_strict = true;
- // Validate the query parameters and network size.
- exit;
- }
- // $_SERVER['HTTP_HOST'] is lowercased here per specifications.
- $origin_host = $_GET['origin_host'];
- // Find the next site that needs to be visited in the $network, by removing
- // the origin site re-keying the array.
- foreach ($network as $delta => $site) {
- }
- }
- // We are on the site which has started the process.
- // No need to create the cookie, the site already handled its login / logout.
- // Start from the beginning of the redirect list.
- }
- else {
- sso_create_cookie($_GET['op']);
- foreach ($network as $delta => $site) {
- $current_site_delta = $delta;
- break;
- }
- }
- exit;
- }
- $next_site_delta = $current_site_delta + 1;
- // Redirect to the next network site.
- }
- else {
- // We are at the last network site. In these scenarios, we need to
- // redirect to the destination, or to the original host in case of a logout.
- if ($_GET['op'] == 'login') {
- $redirect_destination = $_GET['destination'];
- }
- else {
- $redirect_destination = ($https ? 'https://' : 'http://') . $_GET['origin_host'];
- }
- }
- }
- // Redirect the user. We need to prevent the redirect from being cached.
- exit;
- /**
- * Validates the query parameters.
- *
- * Required parameters:
- * - op: Tells us what the current operation is: login or logout.
- * - origin_host: Indicates which site initiated the login/logout.
- * Additional required parameter when the operation is "login":
- * - destination: The url to redirect the user to after all redirects are done.
- */
- function sso_validate_query_params() {
- return FALSE;
- }
- return FALSE;
- }
- return FALSE;
- }
- return TRUE;
- }
- /**
- * Creates a cookie signaling the required operation.
- *
- * Removes any conflicting cookies.
- *
- * @param $operation
- * The operation to signal, login or logout.
- */
- function sso_create_cookie($operation) {
- if ($operation == 'login') {
- $remove = 'Drupal.visitor.SSOLogout';
- $create = 'Drupal.visitor.SSOLogin';
- }
- else {
- $remove = 'Drupal.visitor.SSOLogin';
- $create = 'Drupal.visitor.SSOLogout';
- }
- $remove .= '_' . $domain;
- $create .= '_' . $domain;
- }
- // The expiration should be less than the Drupal session duration.
- // The most common Drupal `session.gc_maxlifetime` value is 200000 seconds,
- // so we define the expiration to half a minute before that, accordingly.
- }
- /**
- * Returns an URL to which redirection can be issued.
- *
- * @param string $host
- * @param bool $https
- * @return string
- */
- function sso_redirect_url($host, $https) {
- $host = ($https ? 'https://' : 'http://') . $host;
- }
- 'op' => $_GET['op'],
- 'origin_host' => $_GET['origin_host'],
- );
- if ($_GET['op'] == 'login') {
- $args['destination'] = $_GET['destination'];
- }
- }