Quatuor gagnant: Authentification ADFS SAML 2.0 avec Shibboleth SP 3 sous IIS10 et PHP

Dans cet article nous allons voir comment configurer une fédération SAML 2.0 entre ADFS 2016 et Shibboleth SP 3.0. Dans un second temps, nous verrons comment via PHP récupérer les informations d’identification et claims (assertions) d’un utilisateur précédemment authentifié au travers cette fédération.

Prérequis à cette maquette

Fournisseur d’identité (Idp) : ADFS (Windows Server 2016)
Metadata de l’Idp: https://fs.test.local/FederationMetadata/2007-06/FederationMetadata.xml

Fournisseur de services (Sp):
 Shibboleth SP 3.0
Metadata du SP: https://shibboleth.test.local/Shibboleth.sso/Metadata

Compte utilisateur standard sur l’annuaire Active Directory: localadminuser@test.local

Configuration du serveur applicatif: IIS

Sur le serveur IIS:
Nous partons d’une installation d’un serveur IIS vierge. Seuls les composants ci dessous doivent explicitement être installés:

  • FastCGI est un prérequis à PHP
  • ISAPI Extentions et ISAPI Filter sont des prérequis pour Shibboleth (voir partie « Configuration du serveur applicatif: Shibboleth »)

Un des impondérable à ce type de mécanisme d’authentification est que l’ensemble des endpoints soient en HTTPS. Shibboleth comme ADFS doivent donc présenter des certificats TLS 1.2 sur les différents endpoints.

Dans ce scénario nous allons utiliser des certificats autosignés mais pour des raison de sécurité, notamment en cas de besoin de révocation d’un certificat, une autorité de certification interne ou externe doit être utilisée.

Configuration du serveur applicatif: PHP

Sur le serveur IIS:
Plusieurs méthodes permettent d’installer le composant PHP sur notre serveur IIS. Il est possible d’utiliser la console « New Web Platform Components » mais nous effectuons ici une installation manuelle.

Nous allons avoir besoin de 2 composants: PHP et PHP manager for IIS. Le premier est à télécharger sur le site php.net en suivant le lien ici. Le 2eme, sous forme d’extension pour IIS est à télécharger sur le site IIS.net en suivant le lien ici. PHP manager va nous permettre de configurer PHP via une interface graphique présente dans le manager IIS.

PHP livré sous format ZIP, est à décompressé sous C:\php. L’installation de PHP manager s’effectue sans problème particulier en suivant l’assistant.

Pour vérifier que ces 2 composants sont correctement installés, il suffira de cliquer sur l’icone PHP Manager présents dans le manager IIS:

Il est souvent conseillé de redémarrer un serveur après l’installation d’un composant. Ici, je vous recommande de redémarrer les services IIS via la commande « iisreset » en tant qu’administrateur une fois l’installation de PHP et PHP manager terminée.

Afin de tester le bon fonctionnement de PHP nous pouvons créer le fameux phpinfo(); à la racine du site:

<?php
phpinfo();
?>

Au lancement de la page le résultat attendu doit être la page ci dessous:

Nous pouvons considérer PHP comme fonctionnel. La sécurité doit être renforcée pour une utilisation en production. Vous pouvez suivre ce lien notamment la partie « PHP Security Recommendations » qui est intéressante pour traiter ce point.

 

Configuration du serveur applicatif: Shibboleth SP

Sur le serveur IIS:
Nous allons donc utiliser comme Service Provider l’application Shibboleth SP 3.0. Elle se présente comme une extension ISAPI. Elle est mise en œuvre sous forme de DLL et chargée sous contrôle d’IIS. Je vous propose de consulter cet article pour suivre son installation. Dans la suite nous allons considérer que Shibboleth SP est déjà installé et prêt à fonctionner. Nous verrons donc uniquement la partie paramétrage du produit dans notre contexte.

Le répertoire d’installation de Shibboleth SP est C:\opt\shibboleth-sp. Les répertoires et fichiers ci dessous vont particulièrement nous intéresser:

  •  C:\opt\shibboleth-sp\etc\shibboleth
    – shibboleth2.xml qui contient la configuration générale de Shibboleth
    – attribute-map.xml qui contient la translation des noms d’attributs contenus dans les assertions SAML envoyées par l’IdP vers des en-têtes HTTP exploitables par l’application finale. Nous verrons à la fin de cet article l’exploitation de ces valeurs dans PHP.
    – keygen.bat qu’il faudra exécuter pour générer une nouvelle paire de clés (Signature et Encryption sur SP).
    – partner-metadata.xml est le metadata de l’IDP téléchargé depuis le serveur ADFS 2016.
  • C:\opt\shibboleth-sp\var\log\shibboleth qui contient les fichiers de logs et notamment shibd.log

Fichier shibboleth2.xml

Original:

A remplacer par:

l’id doit correspondre à l’ID du site IIS:

Original:

A remplacer par:

Vous noterez ici que le répertoire /secure/ est par défaut le répertoire où nous ferons appel à Shibboleth comme méthode d’authentification. Ceci indique qu’au chargement de l’URL https://monsite.test.local/secure le module Shibboleth sera appelé et l’authentification requise.
Il est bien évidement possible d’ajouter d’autres répertoires en ajoutant une nouvelle balise <Path name=monrepertoireasecuriser » authType …

Original:

A remplacer par:

L’ApplicationDefaults EntityID (Identifier) doit correspondre à celui qui sera renseigné lors de la création du relying party trust dans ADFS.

Il est à noter que j’ajoute signing= »true » et encryption= »true ». Ces paramètres ne sont pas obligatoire. Par défaut, la signature des SAML_REQUEST et l’encryption des SAML_RESPONSE sont proposées par Shibboleth. En cas de suppressions de ces certificats coté ADFS, Shibboleth ne signera plus les SAML_REQUEST et ne chiffrera plus les SAML_RESPONSE. Passer ce paramètre à « true » permet d’imposer par le SP la signature et le chiffrement. Les 2 certificats permettant cette tache (voir execution du keygen.bat) sont présents dans le metadata du SP et donc intégrés et utilisé par ADFS.

Le SSO EntityID correspond à l’entityID présent dans le metadata de l’IDP téléchargeable à l’URL suivante: https://fs.test.local/FederationMetadata/2007-06/FederationMetadata.xml

Nous en profitons pour renforcer les contrôles de sécurité en passant checkAddress et handlerSSL à true et cookieProps à https. Nous pouvons supprimer la partie discoveryProtocol et discoveryURL, ADFS ne possédant pas cette fonctionnalité de découverte.

Enfin, nous supprimons l’acl présente sur la page /Status et passons le showAttributeValues de /Session à true.

 

Fichier attribute-map.xml

Ce fichier va permettre d’indiquer à Shibboleth de mapper les attributs présents dans notre jeton SAML avec des id que nous allons récupérer sous forme de variable dans PHP.

Nous pouvons supprimer l’ensemble des exemples présents par défaut dans ce fichier XML et le remplacer par ce que nous souhaitons exploiter dans notre jeton SAML:

 

Exécution du keygen.bat

Dans ce scénario, nous allons utiliser la possibilité de signer les SAML REQUEST ou chiffrer les SAML_RESPONSE avec les certificats présents et inscrits dans le metadata coté SP. Il nous faut exécuter en tant qu’admin les commandes ci dessous dans un « cmd »:

C:\opt\shibboleth-sp\etc\shibboleth> keygen.bat -h shibboleth.test.local -e https://shibboleth.test.local -f -n sp-encrypt
C:\opt\shibboleth-sp\etc\shibboleth> keygen.bat -h shibboleth.test.local -e https://shibboleth.test.local -f -n sp-signing

Les nouvelles paires de clés sont alors créés sous C:\opt\shibboleth-sp\etc\shibboleth

  • sp-encrypt-cert.pem – correspond à la clé publique du certificat d’encryption coté SP
  • sp-encrypt-key.pem – correspond à la clé privée du certificat d’encryption coté SP
  • sp-signing-cert.pem – correspond à la clé publique du certificat de signature coté SP
  • sp-signing-key.pem – correspond à la clé privée du certificat de signature coté SP

Le fichier shibboleth2.xml en fait référence ci dessous :

Fichier partner-metadata.xml

Il s’agit ni plus ni moins des métadonnées de notre IDP coté ADFS, téléchargeable en suivant le lien https://fs.test.local/FederationMetadata/2007-06/FederationMetadata.xml. Ce fichier est à copier dans C:\opt\shibboleth-sp\etc\shibboleth et à renommer partner-metadata.xml

 

L’ensemble de la configuration de Shibboleth SP est à présent terminée. Pour appliquer celle ci, il suffit de redémarrer le service Shibboleth Daemon (Default).
Le fichier C:\opt\shibboleth-sp\var\log\shibboleth\shibd.log doit nous indiquer aucune erreur au démarrage.

Pour vérifier que la configuration est effective, il doit être possible de consulter le metadata du serveur Shibbolet via l’URL ci après: https://shibboleth.test.local/Shibboleth.sso/Metadata
C’est d’ailleurs cette dernière URL que nous allons utiliser pour initier la configuration du relying party trust dans ADFS.

Configuration du fournisseur d’identité: ADFS

Sur le serveur ADFS:
La configuration des services ADFS s’effectue via la console « AD FS Management ». Nous allons créer un relying party trust  à partir des informations présentes dans le metadata de Shibboleth.
En cliquant sur Add Relying Party Trust… nous pouvons sélectionner le type d’application souhaitée: Claim aware.

Nous allons à présent utiliser la fonction d’import automatique de la configuration Shibboleth présente dans le metadata. Ce metadata sera consulté 1 fois par jour pour prendre en compte les éventuelles modifications que nous aurions apportées à la configuration Shibboleth.

Saisir le nom de notre Relying Party Trust:

Nous ne possédons pas dans notre scénario de fournisseur de MFA et souhaitons au passage une configuration sans politique de contrôle. L’ensemble de nos utilisateurs présents dans notre annuaire Active Directory pourront donc s’authentifier au travers ce Relying Party Trust. Nous pouvons sélectionner l’option « Permit Everyone »:

Avant de valider la fin de la configuration, nous allons vérifier que le Relying party identifier et bien identique à ApplicationDefaults EntityID de notre Shibboleth :

Nous laisserons la case « Configure claims issuance policy for this application » cochée. La fenêtre nous permettant d’éditer le contenu de notre claim s’ouvre.

Le bouton « Add Rules » va nous permettre d’ajouter les 2 règles ci dessous. Dans notre scénario, nous allons ajouter l’UPN et le Display Name de l’utilisateur.

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"),
query = ";userPrincipalName,displayName;{0}", param = c.Value);

Nous en profiterons pour créer une règle de transformation afin de préciser le Name ID et son formatage:

c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
=> issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");

La configuration du Relying Party Trust ADFS est a présent terminée.

Récupération et exploitation des assertions par PHP

Une fois l’utilisateur authentifié, Shibboleth va récupérer les assertions transmises par le client à travers la SAML_RESPONSE et configurées/mappées dans le fichier attribute-map.xml. Il va les mettre à disposition sous fourme de variable dans un tableau dans les en-têtes HTTP coté serveur. Les en-têtes HTTP permettent au client et au serveur de transmettre des informations supplémentaires avec la demande ou la réponse. Shibboleth va donc en profiter pour ajouter des en-têtes commençant par:

  • HTTP_XXXX: Pour les valeurs configurées dans attribute-map.xml ou XXXX représente  l’id de l’assertion.
  • HTTP_SHIBZZZZZ: Pour valeurs internes positionnées automatiquement par la brique Shibboleth.

Vue des en-têtes HTTP:

Vue du fichier attribute-map.xml de Shibboleth

Il est a noter que variable REMOTE_USER est une variable spéciale. Elle prend la valeur déjà présente dans PERSISTANT-ID car nous avons configuré le SP Shibboleth pour cela (élément ApplicationDefaults/REMOTE_USER de shibboleth2.xml). Elle est présente ici pour des raisons de compatibilité:

Afin de récupérer ces valeurs, nous pouvons utiliser une simple fonction PHP:

<?php 
print_r($_SERVER) 
?>

Cette fonction va nous afficher un tableau contenant en-têtes coté serveur:

 

Pour pouvoir exploiter ces valeurs et par exemple récupérer le nom de l’utilisateur, il faudra créer une page index.php sous le répertoire/secure/ (https://shibboleth.test.local/secure/) contenant la même fonction utilisée ci dessous mais précisant la valeur que nous souhaitons récupérer sous forme de variable.

<html>
 <head>
  <title>Bonjour</title>
 </head>
 <body>
 <?php 
$login = $_SERVER[HTTP_NAME];
echo 'Bonjour ';
echo $login; 
?>
 </body>
</html>

Au lancement de la page et après authentification par notre IDP,  le résultat doit afficher la valeur contenant le nom de l’utilisateur authentifié:

 

2 Comments

Add a Comment

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *