Identification par OpenID Connect des utilisateurs identifiés avec Kerberos

, par B. Degoy

L’utilisateur Windows qui a créé une session avec Active Directory (il a déjà fourni son login et son mot de passe) pourra se connecter aux applications Web protégées par OAuthSD sans avoir à entrer dans une nouvelle procédure d’identification.

Kerberos agit alors vis-à-vis du serveur OIDC comme un Fournisseur d’identité OIDC (OIDC Identity Provider).

La solution décrite s’adresse au serveur Kerberos sans passer pas la passerelle Navigateur->Apache->application (mod_auth_kerb) qui est peu portable et instable.

A propos du logo de Kerberos : dans la mythologie grecque, Cerbère (en grec ancien Κέρϐερος / Kérberos) est le chien à trois têtes gardant l’entrée des Enfers (Wikipedia). Ce logo est adopté par le MIT pour son protocole krb5 qui est utilisé ici.

Objectif

L’utilisateur qui s’est identifié sur le réseau local avec Active Directory est inscrit sur le serveur Kerberos du domaine.

Il s’agit de faire en sorte que cet utilisateur soit également identifié par OIDC, donc sans avoir à suivre une nouvelle procédure de login dans les applications clientes du serveur OAuthSD de l’organisation.

On peut donc dire que le "SSO" d’OauthSD (la connexion unique) héritera de celui de Kerberos.

Solution s’adressant directement au serveur Kerberos

Cette approche est complète car elle permet d’obtenir non seulement le login de l’utilisateur mais également des informations permettant son identification.

De plus, elle ne fait pas appel à la passerelle entre Kerberos et le navigateur, ce qui permet :
– d’éviter des problèmes de configuration des navigateurs des utilisateurs,
– d’améliorer la sécurité en restant dans une liaison serveur-serveur (le navigateur ne voit pas passer d’information d’authentification).

Concepts

Le protocole Kerberos définit la façon dont les utilisateurs interagissent avec un service réseau pour avoir accès aux ressources du réseau.

Pour une présentation générale de Kerberos, voyez : Exploration du protocole KERBEROS

Dans Windows, l’ordinateur client est membre d’un domaine AD DS (Active Directory Domain Services) et le ticket TGT prouve que le contrôleur de domaine Kerberos a authentifié les informations d’identification fournies par l’utilisateur de l’ordinateur client.

Si la finalité et le fonctionnement de Kerberos ressemblent à ceux d’OpenID Connect (OIDC), leur niveau fonctionnel (au sens couches ISO du terme) n’est pas le même :

Comparaison fonctionnelle OIDC / Kerberos
OIDC Kerberos
Objectif Authentification des internautes par les applications Web identification des utilisateurs, des machines et des ressources sur le réseau local
Niveau de communication Web Réseau local
Protocole HTTP TCP
Le client est Une application ouverte sur le serveur HTTP, sur l’user-agent ou native capable de protocole HTTP Toute application native fonctionnant sur la machine de l’utilisateur final (ordinateur client) capable d’ouvrir un socket [1] [2].
Le sujet est L’utilisateur final (ou l’application si elle demande l’authentification pour elle-même) L’utilisateur ayant ouvert la session Windows

Le tableau suivant met en parallèle les concepts des deux systèmes [3].

Correspondance des Concepts
Auth2 Kerberos
Serveur d’autorisation (AS) Centre de distribution de clés (KDC)
Authentication controller Authentication service (AS)
Authorization Code Ticket to Get Tickets ou Ticket-Granting Ticket (TGT)
Token controller Ticket Granting Service (TGS)
Access token Service ticket
URL de la ressource Service Principal Name (ou simplement Principal), SPN

Note à propos de la sécurité

Notons que OIDC opère au niveau applicatif (et non au niveau du réseau), ce qui contribue à l’approche "accès zéro-confiance au réseau" (ZTNA).
Donc il ne faudrait pas utiliser Kerberos ? Ici, nous utilisons Kerberos pour l’identification et l’autorisation de l’utilisateur. L’accès à l’application (ou de l’application aux ressources protégées) reste contrôlé au niveau applicatif.

Pourquoi ne pas utiliser mod_auth_kerb ?

Pour réaliser l’intégration de Kerberos comme pourvoyeur d’identité au profit d’OpenID Connect, un premier problème à résoudre consiste à passer les informations Kerberos de la couche de transport TCP à la couche protocole HTTP.

Quand on cherche comment le problème est résolu, on trouve généralement des applications de l’extension Apache mod_auth_kerb.

mod_auth_kerb définit la variable d’environnement REMOTE_USER avec l’identification du client, ce que l’on peut récupérer dans l’application. Cela suppose l’intégration des informations Kerberos dans le Header de la requête HTTP.

Les principaux inconvénients sont les suivants :
– Pour fonctionner, cela exige de configurer le navigateur Web pour qu’il utilise réellement l’authentification HTTP Negotiate, dont les détails varient d’un navigateur à l’autre. Certains navigateurs n’implémentent pas cette fonctionnalité.
– La mise à jour ou la reconfiguration du poste de travail de l’utilisateur peut écraser la configuration ou changer le navigateur par défaut.
– Le serveur Apache est nécessaire, Nginx ne semble pas pouvoir être utilisé.

Nous considérerons donc que la solution n’est ni portable ni stable.

Le flux décrit ci-dessous, qui s’adresse directement au serveur Kerberos du domaine, évite les difficultés et présente une meilleurs sécurité en évitant de passer par le navigateur .

Voici l’implémentation d’OAuthSD :

P.-S.

Flux de l’Authentification OIDC avec Kerberos

(Nota : développement en cours)

Le serveur OIDC tente d’utiliser une éventuelle authentification Kerberos avant toute autre méthode d’identification de l’utilisateur. Le flux est le suivant :

– l’application cliente demande un code d’autorisation au serveur OAuthSD (contrôleur Authorize) en passant le scope ’kerberos’,
– En se fondant sur l’adresse de sous-réseau, OAuthSD teste si l’ordinateur client est dans le domaine ou le sous-domaine autorisé du réseau local (précisé dans la configuration du serveur OAuthSD),
– OAuthSD interroge le DNS du domaine avec l’adresse de sous-réseau et obtient l’id de la machine sous la forme monserveur.monreseau.local et forme l’adresse kerberos HTTP/monserveur.monreseau.local@MONRESEAU.LOCAL.
– OAuthSD se connecte à Kerberos en créant un principal kerberos avec les identifiants de l’administrateur,
– OAuthSD examine si la machine a un ticket de session valide, et en extrait l’identité de l’utilisateur,
– OAuthSD détruit sa connexion Kerberos.
– si la machine est authentifié par Kerberos, le serveur OAuthSD vérifie que l’utilisateur figure bien dans la table users.
– le serveur OAuthSD crée ou met à jour le cookie SLI [4].

Si l’authentification Kerberos n’est pas autorisée ou échoue, le serveur OAuthSD passe à la méthode d’identification suivante [5].

Dispositions de sécurité

Inscription de l’utilisateur AD sur OAuthSD
Pour améliorer la sécurité, on peut exiger que le contrôleur Authorize vérifie que l’utilisateur AD est également enregistré sur le serveur OAuthSD .
Dans ce cas, l’utilisateur final devra être inscrit indépendamment sur le serveur OAuthSD, avec le même identifiant que sur AD.
Cette disposition est une option contrôlée par la constante de configuration KERB_USER_EQUALS_OIDC_USER définie à True par défaut.

Le scope ’kerberos’
Ce scope doit figurer dans la liste des scopes disponibles pour l’application. Pour autoriser l’identification Kerberos, l’application cliente de OAuthSD doit faire appel au contrôleur Authorize en réclamant ce scope.
Ainsi, la possibilité d’un SSO avec Kerberos reste sous le contrôle de l’administrateur du serveur OAuthSD et celui du concepteur de l’application cliente.

Un peu de technique...

Référence : https://docstore.mik.ua/manuals/php...

Création du principal kerberos
OAuthSD ouvre une connexion à la bibliothèque KADM5 avec les identifiants de l’administrateur du serveur Kerberos.
OAuthSD obtient un handle vers le gestionnaire KADM5 (ou false en cas d’erreur), dont on se servira pour interroger LDAP et obtenir les informations sur l’utilisateur, en particulier pour vérifier qu’il est authentifié sur le réseau.

<?php

/**
* Initialise la connexion avec le principal de l'administrateur du domaine $realm et retourne les informations sur un utilisateur $user.
* $user : nom de l'utilisateur,
* $admin_server : nom du serveur Kerberos sur le réseau local,
* $realm : Domaine d'identification,
* $admin_principal : Principal de l'administrateur du serveur Kerberos,
* $password : Mot de passe de l'administrateur du serveur Kerberos.
*/

function kerberos_getinfos( $user, $admin_server, $realm, $principal, $password ) {
    
    $handle = kadm5_init_with_password($admin_server, $realm, $admin_principal, $admin_password);

    $options = kadm5_get_principal($handle, $user . '@' . $realm);
 
    kadm5_destroy($handle); 

    return $keys = array_keys($options);

}
?>

Identifier la machine locale

Lorsqu’une application demande au serveur OIDC une authentification pour un utilisateur final, elle s’adresse au contrôleur Authorize qui :
– détermine l’adresse IP sur le réseau local de la machine depuis laquelle l’utilisateur s’est identifié sur Active Directory,
– interroge le DNS pour obtenir le nom de la machine avec l’IP ( Ceci nécessite que tous les ordinateurs joints au domaine sont enregistrés au sein du DNS du réseau local, avec leur reverse renseigné ).

Authorize peut alors utiliser krb5 pour adresser la machine sur AD avec l’identifiant <nom de la machine>.<monreseau.local>.

Notes

[1] Ce qui inclut les applications ouvertes sur le serveur HTTP mentionnées à gauche, pourvu qu’il puisse accéder au serveur Kerberos du domaine.

[2] Donc n’importe quelle application, y compris un malware : on ne sait pas où vont les données !

[3] Il ne s’agit pas d’identité puisque le niveau de communication et le sujet de l’authentification ne sont pas les mêmes d’un côté à l’autre. Il faut lire le tableau comme "Dans OIDC xxx joue le rôle du yyy de Kerberos"

[4] A partir de ce moment, la session SLI d’OAuthSD et démarrée. Dans l’état actuel du développement, elle vivra indépendamment de la session Active Directory.

[5] Dans l’état actuel du développement, OAuthSD ne traite que les identifications Kerberos et Login/Password.