Implémentation du SSO avec ADFS et Citrix Online – Partie 1

L’objectif de ce billet de blog est de présenter la mise en œuvre des fonctionnalités SSO apportées par le service ADFS dans un environnement d’entreprise utilisant une application hébergée en mode SaaS.

Nous allons pour cela utiliser les services en ligne proposés par Citrix, et sur lesquels nous utiliserons la brique « GotoMeeting » (Service cloud de Web Conferencing).Dans un premier temps, nous mettrons en place l’infrastructure « privée », permettant un accès SSO à l’application Saas depuis l’intranet :

  • Un contrôleur de domaine
  • Un serveur ADFS
  • Des postes de travail joints au domaine ou non

Puis après avoir validé ce mode de fonctionnement, nous mettrons en place la publication de cette fonctionnalité SSO au travers du rôle « Web Application Proxy » de la plateforme Windows 2012 R2 :

Dans ces deux schémas, la logique SSO est la suivante :

  • Un utilisateur accède à la page Web de l’application SaaS.
  • L’application SaaS renvoie une redirection http le serveur ADFS (sauf si la demande est accompagnée d’un jeton de sécurité valide)
  • L’utilisateur s’authentifie auprès du serveur ADFS
  • Le serveur fournit à l’utilisateur un jeton de sécurité signé.
  • L’utilisateur est redirigé vers la plage web de l’application SaaS qui analyse les informations du jeton de sécurité pour décider des accès à fournir à l’utilisateur. Si le jeton est valide, l’utilisateur accède à l’application.

Nous ferons en sorte que l’utilisation de puis l’intranet se fasse par le biais de l’authentification intégrée Windows (le compte de session utilisateur sera utilisé pour obtenir un jeton de sécurité en tâche de fond et sans demande d’authentification supplémentaire). En revanche, les accès effectués depuis l’extérieur se feront par le biais d’un formulaire d’authentification Web.

Prérequis

Les prérequis suivants ne sont pas traités dans ce billet mais doivent cependant être respectés :

  • Disposer d’un abonnement GotoMeeting associé à une adresse de messagerie professionnelle.
  • En prévision d’un usage externe, disposer d’un certificat public dont le nom de sujet correspond au nom externe du service de fédération.
  • Le service ADFS devant être accessible depuis l’Intranet et l’Internet, nous devrons disposer d’enregistrements DNS correspondants au nom du service pour ces deux zones (un enregistrement A dans la zone DNS publique, et un enregistrement A dans la zone DNS interne).

Activation de la fonctionnalité SSO depuis le portail Citrix

La fonctionnalité SSO des services Citrix Online est optionnelle mais dans notre cas, elle est requise. Pour la mettre en place, il faudra disposer d’un nom de domaine DNS public rattaché à notre abonnement et créer un enregistrement DNS de type TXT sur cette zone afin d’en prouver la possession.

Se rendre sur la page https://account.citrixonline.com/organization/administration/ et ouvrir une session à l’aide du compte utilisé pour souscrire l’abonnement.

Il sera demandé de vérifier la possession du nom de domaine revendiqué, soit en y ajoutant un enregistrement DNS, soit en y déposant un fichier texte sur un site web. Une vois la vérification effectuée, le nom de domaine sera confirmé :

Installation du serveur ADFS Windows 2012 R2.

Certificat SSL

Comme évoqué précédemment, nous devons disposer d’un certificat SSL correspondant au nom de notre service ADFS afin que ce dernier soit accessible de l’extérieur. S’agissant d’établir un lien de confiance avec une entité externe, le certificat doit être obtenu auprès d’une autorité de certification publique.

Nous avons donc acquis et placé dans le magasin de certificats de notre serveur ADFS le certificat SSL qui sera utilisé par le service ADFS nommé « sts.dentan.fr ». Ce même nom sera utilisé comme point d’entrée du service ADFS, tant pour les accès internes et externes :

Installation du rôle ADFS

L’installation du rôle ADFS peut se faire depuis une invite PowerShell ou bien par la console du gestionnaire de serveur. Nous privilégions l’installation en PowerShell, plus simple à reproduire et à documenter.

L’installation se fait en lançant la commande suivante :

Install-windowsfeature adfs-federation –IncludeManagementTools


Une fois le rôle en place, son paramétrage initial peut être effectué, toujours depuis le gestionnaire de serveur ou depuis une invite PowerShell.

La création de la ferme ADFS « sts.dentan.fr » via un compte de service géré et l’association au certificat du même nom se fait en lançant les commandes suivantes :

[code language=”powershell”]
# SSL Certificate instantiation
$STScert = Get-ChildItem -Path Cert:LocalMachine\my | where subject -like ‘CN=sts.dentan.fr*’
# ADFS farm setup using Managed Service Account "AADCSVC"
Install-AdfsFarm `
-CertificateThumbprint:$STSCert.Thumbprint `
-FederationServiceDisplayName:"DENTAN Corporation" `
-FederationServiceName:"sts.dentan.fr" `
-GroupServiceAccountIdentifier:"HYBRIDCLOUD\adfssvc$"
[/code]

Etablissement des relations de confiance

Une fois le service ADFS opérationnel, il nous reste à établir les relations de confiance (Relying Party Trust). Ces dernières doivent être établies entre le service ADFS et le fournisseur de service de façon bidirectionnelles :

  • Le fournisseur du service doit connaitre l’identité du service de fédération pour déterminer sur quel URL rediriger les demandes entrantes vis-à-vis d’une organisation (identifiée par le nom de domaine de l’adresse de messagerie) et connaitre la signature de ce même service (clé publique du certificat de signature de jetons) afin de s’assurer de l’authenticité des jetons de sécurité fournis.
  • Le service ADFS doit connaitre l’identité du fournisseur de service ainsi que sa signature (clé publique du certificat) afin de s’assurer de l’authenticité des demandes de fourniture de jetons de sécurité.

Etablissement de la relation de confiance vers Citrix Online

Les informations de relation de confiance sont transmises sous la forme de métadonnées de fédération, soit sous la forme d’un fichier XML, soit sous la forme d’une URL sur laquelle les métadonnées sont publiées. Dans le cas présent, les métadonnées de Citrix Online sont publiées sur l’URL https://login.citrixonline.com/saml/sp . La relation de confiance sera créée sur la base de ce nom en PowerShell:

[code language=”powershell”]
Add-AdfsRelyingPartyTrust `
-MetadataUrl https://login.citrixonline.com/saml/sp `
-Name CitrixOnline `
-AutoUpdateEnabled $true `
-MonitoringEnabled $true
[/code]


Etablissement de la relation de confiance vers le service ADFS

Il nous reste à établir la relation de confiance du côté « Service Provider », étape consistant à fournir les métadonnées du service de fédération ADFS au fournisseur de service « Citrix Online »

La procédure est propre à chaque fournisseur de service, nous allons la configurer sur notre portail d’entreprise Citrix, sur la page https://account.citrixonline.com/organization/administration/ ,dans l’onglet « Fournisseur d’identité » :

La relation de confiance peut être configurée automatiquement, mais nous n’avons pas encore publié notre service ADFS sur Internet et devrons donc récupérer le document XML des métadonnées ADFS pour le fournir dans cette même interface. La récupération des métadonnées dans un fichier .xml se fait en PowerShell :

[code language=”powershell”]
$FederationMetadataUrl = (Get-ADFSEndpoint | where-object {$_.Protocol -eq "Federation Metadata"}).FullUrl.OriginalString
$httpHelper = new-object System.Net.WebClient
$httpHelper.DownloadFile($FederationMetadataUrl , "C:\metadata.xml")
[/code]


Une fois le fichier généré, il suffit de le présenter dans l’interface d’administration, en choisissant l’option « Charger le fichier de métadonnées SAML » :

Le fichier étant consommé, la relation est établie. Les points de terminaison sont parametrés, de même que la clé publique du certificat du serveur ADFS :

Création des règles de transformation

Les règles de transformation sont utilisées pour transformer les revendications SAML en affirmations SAML, c’est-à-dire en jetons de sécurité signés par notre service de fédération. Le service de fédération doit fournir au fournisseur de service les attributs requis par l’application. Il est nécessaire pour cela de connaitre le format sous lequel ces attributs doivent être transmis (information fournie par le fournisseur du service). Dans notre cas, nous allons créer 2 règles :

  • Une règle permettant d’utiliser l’annuaire Active Directory comme magasin de données et utilisant en entrée l’adresse de messagerie des d’utilisateurs pour revendiquer en sortie une donnée de type « E-Mail Address »
  • Une règle permettant de transformer la revendication « E-Mail Address » en revendication sortante « Name ID » en utilisant le format « Email »

Ces règles peuvent être assez facilement définies depuis la console ADFS, mais j’ai décidé de les traiter en PowerShell, certes plus compliqué car la syntaxe du langage de transformation doit être connue, mais présentant l’avantage d’offrir une méthode reproductible (pour obtenir la syntaxe, j’ai utilisé la console ADFS avec laquelle j’ai pu éditer chaque règle et en récupérer son contenu) :

[code language=”powershell”]
# Relying party Rules
$rules = @’
@RuleTemplate = "LdapClaims"
@RuleName = "AD Email"
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/emailaddress"), query = ";mail;{0}", param = c.Value);
@RuleTemplate = "MapClaims"
@RuleName = "Name ID"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
=> 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");
‘@
Set-ADFSRelyingPartyTrust –TargetName citrixonline -IssuanceTransformRules $rules
[/code]


Nous sommes à présent dans notre schéma initial, c’est-à-dire celui dans lequel nous devons être à même d’accéder à l’application SaaS depuis l’Intranet en utilisant une authentification interne :

Le seul élément permettant de valider cette configuration tient à l’approvisionnement de comptes d’utilisateurs dans le portail de services Citrix Online. En effet, la plateforme ADFS permet de valider l’identité d’utilisateurs à condition que ceux-ci existent dans le référentiel du portail de service. Il nous faut donc choisir une méthode d’approvisionnement parmi les solutions suivantes :

Les deux dernières méthodes sortant du périmètre de cet article, nous nous contenterons donc de créer manuellement quelques comptes d’utilisateur de test. Les comptes devront être créés :

  • Dans l’annuaire Active Directory (authentification interne)
  • Dans l’application GoToMeeting (affectation de rôles)

A ce stade, nous pouvons vérifier le fonctionnement du SSO depuis l’Intranet. L’accès à l’application peut se faire :

Validation du mode « Service Provider Initiated »

Depuis un PC membre du domaine, nous ouvrons un navigateur (IE 11 avec Windows 10) sur la page https://global.gotomeeting.com . Le choix de l’authentification d’entreprise se fait par l’option « My CompanyID » qui nécessitera de fournir son adresse de messagerie


Après validation, nous sommes redirigés vers l’application, ou à défaut vers un prompt d’authentification plutôt inattendu dans le cadre d’une solution SSO :

L’explication de ce comportement indésirable vient du fait que notre serveur de fédération ne fait pas nécessairement partie des sites de confiance de la zone Intranet du navigateur. Il suffit de l’y ajouter (manuellement ou par GPO) pour obtenir un fonctionnement presque digne du SSO :

  1. Choisir le mode d’authentification d’entreprise
  2. Saisir son identifiant d’entreprise
  3. On y est


Validation du mode « IDP Initiated »

Dans le mode « SP Initiated », nous avons dû saisir notre identifiant (mais pas le mot de passe) pour faire fonctionner le SSO, ce qui reste moyen. Pour une expérience utilisateur plus simple, il faudrait accéder directement à l’application sans avoir à choisir le mode d’authentification et sans devoir saisir son identifiant.

Cette option est envisageable grâce au mode « IDP Initiated » accessible sur la page https://<fqdnde-la-ferme-adfs>/adfs/ls/idpinitiated.aspx mais par défaut, ce mode renverra sur un portail sur lequel il faudra choisir l’application à lancer parmi celles disponibles, dans le cas présent « Citrix OnLine » :

Une fois ce choix effectué, le SSO fait son travail en tâche de fond et nous accédons directement à l’application :

Il est également possible de préciser cette même l’application visée dans l’URL : https://sts.dentan.fr/adfs/ls/IdPInitiatedSignOn.aspx?LoginToRP=https://login.citrixonline.com/saml/sp, ce qui nous mènera directement à l’application.

Ajustement de la cible applicative.

L’accès à l’application en mode « IDP initiated » nous renvoie sur le portail applicatif Citrix Online, sur lequel nous pouvons choisir d’accéder à l’application Goto Meeting :

Pour traiter ce problème, il nous faut comprendre son origine : nous avons demandé à notre serveur ADFS d’accéder à une application dont il a en charge l’authentification avant d’être redirigés sur cette page. C’est donc le serveur ADFS qui a généré cette redirection, et plus particulièrement la relation de confiance « Citrix Online » elle même créée par le biais des métadonnées publiées par Citrix. C’est donc à ce niveau qu’il faut creuser. Tout d’abord, la relation de confiance est configurée pour se mettre à jour automatiquement sur l’URL du fournisseur de service, nous devons désactiver cette option pour pouvoir modifier le reste :

Le point de terminaison SAML par défaut pointe vers une URL qui n’est pas propre à l’application GoToMeeting, mais générique pour différentes applications en ligne de l’éditeur :

la documentation d’implémentation SSO de GoToMeeting nous indique l’URL du point de terminaison SAML sur https://login.citrixonline.com/saml/global.gotomeeting.com/acs, il faut donc ajouter cette adresse et lui affecter le rôle par défaut en lieu et place de l’adresse initiale.

Nous continuerons à traiter cette opération en PowerShell :

[code language=”powershell”]
# Relying party instantiation
$Trust = Get-AdfsRelyingPartyTrust -Name ‘Citrix Online’
# SAML Endpoints enumeration
[System.Collections.ArrayList]$SamlEndPoints = $Trust.SamlEndpoints
# Default Endpoint instantiation and removal
$DefaultEndPoint = $SamlEndPoints | Where-Object {$_.IsDefault}
$SamlEndPoints.Remove($DefaultEndPoint)
# SAMLAssertionConsumer Endpoints enumeration
$SAMLAssertionConsumer = $SamlEndPoints | Where-Object {$_.protocol -like ‘SAMLAssertionConsumer’}
# End Points builds
$OldDefaultEndpoint = New-AdfsSamlEndpoint -Binding $DefaultEndPoint.Binding -Protocol $DefaultEndPoint.Protocol -Uri $DefaultEndPoint.Location -IsDefault $false -Index $DefaultEndPoint.Index
$NewDefaultEndpoint = New-ADFSSamlEndpoint -Binding ‘POST’ -Protocol ‘SAMLAssertionConsumer’ -Uri ‘https://login.citrixonline.com/saml/global.gotomeeting.com/acs’ -IsDefault $true -Index (($SAMLAssertionConsumer.count) + 1)
# Add Endpoints to Array
$SamlEndpoints.add($NewDefaultEndpoint) | Out-Null
$SamlEndpoints.add($OldDefaultEndpoint) | Out-Null
# Set Relying party trust parameters
Get-AdfsRelyingPartyTrust -Name "Citrix Online" | Set-ADFSRelyingPartyTrust -MonitoringEnabled $false -AutoUpdateEnabled $false
Get-AdfsRelyingPartyTrust -Name "Citrix Online" | Set-ADFSRelyingPartyTrust -SamlEndpoint $SamlEndpoints
[/code]

Après cela, l’accès à la page depuis une session interne (validée par un contrôleur de domaine) nous renvoie directement) notre espace utilisateur GoToMeeting sans aucune demande interaction, c’est bien le SSO que l’on attendait:

Utilisation de différents navigateurs

La plateforme ADFS utilise le champ « UserAgent » des requêtes entrantes pour déterminer le type d’authentification applicable. La stratégie globale d’authentification permet de traiter différemment les demandes internes vis-à-vis des demandes externes (intranet vs extranet).

Cette information est accessible via la commande « Get-AdfsGlobalAuthenticationPolicy ». On voit que dans notre cas :

  • Les demandes internes sont soumises à une authentification par formulaire ou « Windows »
  • Les demandes externes sont soumises à une authentification par formulaire
  • Le « Fallback » vers l’authentification Windows est activé. Ce point sera détaillé plus loin.

Nous nous intéresserons dans un premier temps aux demandes internes. Quelle est la signification de « FormsAuthentication », « WindowsAuthentication » ? Et quel est donc ce paramètre « WindowsIntegratedFallbackEnabled » ?

Ces deux paramètres signifient que les demandes internes seront soumises si possible à une authentification Windows (toujours traitée en priorité) et que si celle-ci n’est pas possible, elles seront soumises à une authentification par formulaire web.

Concrètement, la détermination du type de demande se fait au travers de la chaine « User-Agent » du navigateur utilisé:

Si le User-Agent correspond à une plateforme connue (Internet Explorer par exemple), alors l’authentification Windows est utilisée. Dans le cas d’un accès interne, l’authentification intégrée est utilisée et tout se fait sans aucune interaction utilisateur (SSO).

Dans le cas contraire, l’authentification par formulaire est utilisée (c’est le fameux « fallback »)

La liste des « User-Agents » connus est consultable et même modifiable en PowerShell. Ceci nous sera fort utile pour la prise en charge de toutes les versions de navigateurs plus récents que ceux nativement connus par ADFS 2012 R2 (Internet Explorer 11, Edge, et même Chrome ou FireFox…), le tout est de connaitre son « User-Agent » pour l’ajouter à la liste.

Pour obtenir la liste des navigateurs pris en charge ;

[code language=”powershell”]
[System.Collections.ArrayList]$UserAgents = Get-AdfsProperties | Select-Object -ExpandProperty WiaSupportedUserAgents
[/code]


Dans cette configuration, l’accès à notre application en mode « IDP Initiated » avec Internet Explorer 11 nous mène directement à notre espace applicatif, tandis que la même demande initiée avec Edge nous dirige vers un formulaire d’authentification (au design légèrement modifié pour l’occasion)

Internet Explorer:

Edge:

Il suffit de rajouter les agents appropriés (Edge et Chrome par exemple) pour que ces navigateurs traitent les demandes en authentification Windows Intégrée :

[code language=”powershell”]
[System.Collections.ArrayList]$UserAgents = Get-AdfsProperties | Select-Object -ExpandProperty WiaSupportedUserAgents
$UserAgents.add(‘Edge/12’) | Out-Null
$UserAgents.add(‘Edge/13’) | Out-Null
$UserAgents.add(‘Edge/14’) | Out-Null
$UserAgents.add(‘Chrome/49.0’) |Out-Null
Set-AdfsProperties -WIASupportedUserAgents $UserAgents
[/code]


Nous avons alors atteint notre premier objectif : mettre à disposition en interne le mécanisme SS0 d’une application SaaS. Ce mécanisme fonctionne de façon transparente pour les navigateurs de la famille Internet Explorer, Chrome et Edge.

Dans le prochain article, nous verrons comment le rôle “Web Application Proxy” nous permettra de publier cette infrastructure sur Internet afin de couvrir  les besoins de nomadisme.

Une réflexion au sujet de « Implémentation du SSO avec ADFS et Citrix Online – Partie 1 »

Laisser un commentaire

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