PI Services

Le blog des collaborateurs de PI Services

Le fichier NetLogon.dns

Bonjour à tous,

Aujourd'hui nous allons partir à la découverte du fichier NetLogon.dns

Vous trouverez ce fichier, propre à chaque contrôleur de domaine, dans le dossier %systemroot%\System32\Config.

Comme vous le savez surement, les services AD et DNS sont très étroitement liés car les informations relatives aux différents contrôleurs de domaine ou aux différents sites AD sont stockées dans la zone DNS de la forêt AD correspondante. 

Celle-ci contient donc des enregistrements A faisant référence directement aux adresses IP des contrôleurs de domaine ou des enregistrements SRV permettant aux postes clients de la forêt AD de pouvoir accéder aux services essentiels AD.

Ce fichier intéressera donc en premier lieu :

  • Ceux qui doivent résoudre des problèmes relatifs au fonctionnement des services AD et qui ont localisé des irrégularités au niveau des enregistrements stockés dans la zone DNS AD
  • Ceux dont la zone DNS correspondant à la forêt AD se trouve sur un serveur DNS non Microsoft (gestion "manuelle" des enregistrements)

Un exemple valant mieux que 1000 mots, vous trouverez ci-dessous le contenu de ce fichier avec l'ensemble des enregistrements mentionnés ci-dessus :

Bonne exploration !

Windows : Error 997 Overlapped I/O operation is in progress.

Problème :

Alors que je voulais installer "microsoft report viewer 2008" sur mon Server WSUS un petit message d'erreur est apparu.

 

Impossible d'installer le package même après reboot du serveur.

Ce problème connu chez Microsoft serait lié à la KB2918614, cette dernière utiliserait des certificats et clés de cryptage pour hacher les fichiers d'installation avec le profil utilisateur connecté.

Cependant un utilisateur avec un profil temporaire ou le Default profil, n'est pas autorisé à utiliser des certificats et clés de cryptage, par conséquent lorsqu'un utilisateur avec un profil temporaire ou le Default profil tente d'installer un package msi, l'installation échoue et retourne le message d'erreur.

Solution :

Pour solutionner ce problème il suffit de renommer le répertoire ci dessous :

C:\ProgramData\Microsoft\Crypto\RSA\S-1-5-18 

En

C:\ProgramData\Microsoft\Crypto\RSA\S-1-5-18_BAK

Relancez l'installation, ça fonctionne.

SCOM – SQL – Trois requêtes d’inventaires des overrides par type d’objet.

Un peu a la manière du précédent post sur l’inventaire des overrides, les trois requêtes suivantes permettent de lister les overrides selon les types d’objet “Rule”, “Monitor” et “Discovery”.

 

 

/* All Overrides for Rules of language code EUN and FRA, with Original MP and Rule, Parameter Name, Override Value, Scope and Containing MP */ Use OperationsManager SELECT mpv2.DisplayName as Rule_MP_Name ,rv.DisplayName as Rule_Name ,IsEnabledByDefault = CASE WHEN rv.Enabled = '0' THEN 'NO' WHEN rv.Enabled <> '0' THEN 'YES' END ,op.OverrideableParameterName as Overrideable_Parameter ,mo.Value as Override_Value ,IsEnforced = CASE WHEN mo.Enforced = '0' THEN 'NO' WHEN mo.Enforced = '1' THEN 'YES' END ,mt.TypeName as Override_Scope ,bme.DisplayName as Override_InstanceName ,bme.Path as Override_InstancePath ,mpv.DisplayName as Override_MP_Name FROM ModuleOverride mo INNER JOIN managementpackview mpv on mpv.Id = mo.ManagementPackId INNER JOIN ruleview rv on rv.Id = mo.ParentId INNER JOIN ManagedType mt on mt.managedtypeid = mo.TypeContext INNER JOIN [dbo].[OverrideableParameter] op on op.OverrideableParameterId = mo.OverrideableParameterId INNER JOIN managementpackview mpv2 on mpv2.Id = rv.ManagementPackId LEFT JOIN BaseManagedEntity bme on bme.BaseManagedEntityId = mo.InstanceContext WHERE mpv.Sealed = 0 AND rv.LanguageCode in ('ENU','FRA') AND mpv.LanguageCode in ('ENU','FRA') AND mpv2.LanguageCode in ('ENU','FRA') --ORDER BY mpv2.DisplayName

 

/*All Overrides for Monitor of language code EUN and FRA, with Original MP and Monitor, Parameter Name, Override Value, Scope and Containing MP */ Use OperationsManager SELECT mpv2.DisplayName as Monitor_MP_Name ,mv.DisplayName as Monitor_Name ,IsEnabledByDefault = CASE WHEN mv.Enabled = '0' THEN 'NO' WHEN mv.Enabled <> '0' THEN 'YES' END ,op.OverrideableParameterName as Overrideable_Parameter ,mo.Value as Override_Value ,IsEnforced = CASE WHEN mo.Enforced = '0' THEN 'NO' WHEN mo.Enforced = '1' THEN 'YES' END ,mt.TypeName as Override_Scope ,bme.DisplayName as Override_InstanceName ,bme.Path as Override_InstancePath ,mpv.DisplayName as Override_MP_Name FROM MonitorOverride mo INNER JOIN managementpackview mpv on mpv.Id = mo.ManagementPackId INNER JOIN monitorview mv on mv.Id = mo.MonitorId INNER JOIN ManagedType mt on mt.managedtypeid = mo.TypeContext INNER JOIN [dbo].[OverrideableParameter] op on op.OverrideableParameterId = mo.OverrideableParameterId INNER JOIN managementpackview mpv2 on mpv2.Id = mv.ManagementPackId LEFT JOIN BaseManagedEntity bme on bme.BaseManagedEntityId = mo.InstanceContext WHERE mpv.Sealed = 0 AND mv.LanguageCode in ('ENU','FRA') AND mpv.LanguageCode in ('ENU','FRA') AND mpv2.LanguageCode in ('ENU','FRA') ORDER BY mpv2.DisplayName

 

-- All Overrides for Discoveries of language code EUN and FRA, with Original MP and Discovery, Parameter Name, Override Value, Scope and Containing MP */ Use OperationsManager SELECT mpv2.DisplayName as Discovery_MP_Name ,dv.DisplayName as Discovery_Name ,mo.ParentType ,IsEnabledByDefault = CASE WHEN dv.Enabled = '0' THEN 'NO' WHEN dv.Enabled <> '0' THEN 'YES' END ,op.OverrideableParameterName as Overrideable_Parameter ,mo.Value as Override_Value ,IsEnforced = CASE WHEN mo.Enforced = '0' THEN 'NO' WHEN mo.Enforced = '1' THEN 'YES' END ,mt.TypeName as Override_Scope ,bme.DisplayName as Override_InstanceName ,bme.Path as Override_InstancePath ,mpv.DisplayName as Override_MP_Name FROM ModuleOverride mo INNER JOIN managementpackview mpv on mpv.Id = mo.ManagementPackId INNER JOIN DiscoveryView dv on dv.Id = mo.ParentId INNER JOIN ManagedType mt on mt.managedtypeid = mo.TypeContext INNER JOIN [dbo].[OverrideableParameter] op on op.OverrideableParameterId = mo.OverrideableParameterId INNER JOIN managementpackview mpv2 on mpv2.Id = dv.ManagementPackId LEFT JOIN BaseManagedEntity bme on bme.BaseManagedEntityId = mo.InstanceContext WHERE mpv.Sealed = 0 AND dv.LanguageCode in ('ENU','FRA') AND mpv.LanguageCode in ('ENU','FRA') AND mpv2.LanguageCode in ('ENU','FRA') AND mo.ParentType = 'Discovery' ORDER BY mpv2.DisplayName

SCOM - Requête SQL pour afficher toutes les règles ayant au moins un override ou aucun

 

 

-- QUERY TO DISPLAY ALL RULES WITH TARGET CLASSES AND THEIR OVERRIDE STATE (ANYWAY MORE THAN 1 OVERRIDE PER RULE) - (FILTERED ON 'ENU' AND 'FRA' LANGUAGES) -- THE FINAL 'GROUP BY' CLAUSE IS TO DISPLAY ONLY ONE RULE OCCURENCE (WE ONLY WANT TO KNOW THAT RULE IS OVERRIDEN AT LEAST ONE TIME. -- THAT IS EQUIVALENT TO DELETE THE 'ALL' STATEMENT IN UNION CLAUSE. PRINT 'ALL RULES THAT IS OVERRIDEN AT LEAST 1 TIME OR NOT'; WITH TEMP1 (Rule_Name,Target_Class,Override_State) AS ( SELECT rv.DisplayName as Rule_Name ,MTV.DisplayName as Target_Class ,Override_State = CASE WHEN mo.ParentId is null THEN 'NOT OVERRIDEN' WHEN mo.ParentId is not null THEN 'OVERRIDEN' END FROM RuleView rv FULL JOIN ModuleOverride mo on rv.Id = mo.ParentId INNER JOIN [dbo].[ManagedTypeView] MTV on rv.TargetMonitoringClassId = MTV.Id WHERE rv.Id not in (select mo.ParentId from ModuleOverride mo) AND rv.LanguageCode in ('ENU','FRA') AND MTV.LanguageCode in ('ENU','FRA') UNION ALL SELECT rv.DisplayName as Rule_name ,MTV.DisplayName as Target_Class ,Override_State = CASE WHEN mo.ParentId is null THEN 'NOT OVERRIDEN' WHEN mo.ParentId is not null THEN 'OVERRIDEN' END FROM RuleView rv FULL JOIN ModuleOverride mo on rv.Id = mo.ParentId JOIN [dbo].[ManagedTypeView] MTV on rv.TargetMonitoringClassId = MTV.Id WHERE rv.Id in (select mo.ParentId from ModuleOverride mo) AND rv.LanguageCode in ('ENU','FRA') AND MTV.LanguageCode in ('ENU','FRA') ) SELECT Rule_Name ,Target_Class ,Override_State FROM TEMP1 GROUP BY Rule_Name,Target_Class,Override_State ORDER BY Rule_Name

Le champ CountryOrRegion génére un filtre OPATH invalide dans une liste de distribution dynamique

Problème:

Impossible de requêter les membres d'un groupe dynamique Exchange ayant un paramètre de filtrage sur le champ "CountryOrRegion".

L'erreur spécifiée est générique et indique que le filtre OPATH ou LDAP est invalide:

"La chaîne de filtre de prévisualisation du destinataire $VotreFiltre n'est ni un filtre OPath valide ni un filtre LDAP valide. Utilisez le paramètre -RecipientPreviewFilter avec une chaîne de filtre OPath valide ou une chaîne de filtre LDAP valide."

Cause:

Une des raisons possible à ce message d'erreur est que la valeur du champ CountryOrRegion ait été déclarée depuis une console Powershell en français (ou toute langue autre que l'anglais). En effet la console powershell interprète et traduit directement la valeur spécifiée pour l'attribut CountryOrRegion.

Par exemple, si vous spécifiez la valeur "CountryOrRegion -eq Germany" ou "CountryOrRegion -eq DE" et que votre console powershell est en français, la valeur retenue et transmise dans le filtre OPATH sera "CountryOrRegion -eq Allemagne".

Ceci est problématique car les serveurs Exchange installés en anglais seront incapables de traduire cette valeur et vous ne pourrez pas interagir avec cette liste de distribution dynamique pour la partie modification et récupération des membres, la liste en elle-même devrait normalement être fonctionnelle. 

Autre raison possible, la valeur n'est pas renseignée correctement.

Les valeurs doivent correspondre à la norme ISO 3166-1 de l'appellation des pays.

https://fr.wikipedia.org/wiki/ISO_3166-1

Solution:

Actuellement, ce problème est considéré comme un fonctionnement standard du produit, pour corriger les listes de distributions dynamiques en erreur, il vous faudra les recréer depuis une console en anglais.

 

 

SQL Server–Optimiser les paramètre d’exécution parallèle (1/2)

Introduction :

SQL Server est conçu pour optimiser l’exécution des requêtes de manière transparente, l’une des méthodes utilisé par SQL est le calcul parallélisé de requêtes.

Cette méthode d’optimisation consiste à diviser l’exécution d’une requête à travers threads afin d’accélérer l’exécution de la requête.

Ce post composé de deux parties à pour objectif de présenter les paramètres suivants :

  • MAXDOP (partie 1/2),
  • Cost Threshold for Parallelism (partie 2/2)

Explication :

Le paramètre MAXDOP signifie “Max Degree of Parallelism”, ce paramètre permet de maitriser le nombre maximum de processeurs pouvant intervenir dans l’exécution d’une requête parallélisée, il est important de comprendre que ce paramètre ne peut être utilisé pour limiter le nombre de processeurs utilisés par SQL.

Ce lien liste les valeur recommandées par Microsoft afin de paramétrer cette valeur en fonction des versions de SQL Serveur, ce lien peut également être utilisé pour calculer la valeur optimale à positionner. Il est bien entendu nécessaire de tester les différentes configurations en fonction de la charge soumise par l’application qui utilise le serveur SQL.

Réalisation

Le paramètre MAXDOP peut être modifié depuis les propriétés de l’instance SQL concernée dans la partie Advanced->Parallelism :

image

Ou via la requête suivante (en remplaçant VALEUR par la valeur désirée) :

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
dbo.sp_configure 'max degree of parallelism', VALEUR;
GO

RECONFIGURE;
GO

La modification du paramètre MAXDOP est prise en compte sans qu’il n’y a à redémarrerredemmarer l’instance.

Sources :

SQL Server–Optimiser les paramètre d’exécution parallèle (2/2)

Introduction :

Comme vu dans le post précèdent, SQL Server dans sa configuration par défaut optimise automatiquement l’exécution des requêtes, notamment en répartissant son exécution à travers différents threads.

Ce post composé de deux parties à pour objectif de présenter les paramètres suivants :

  • MAXDOP (partie 1/2),
  • Cost Threshold for Parallelism (partie 2/2)

La partie 2/2 de ce post auras pour objectif de configurer SQL afin que seules les requêtes considérées comme volumineuses ne soient traitées en parallèle.

Explication :

Le paramètre “Count Threshold for Parallelism” permet à SQL de ne paralléliser que les requêtes dont le coût d’exécution d’un plan en série (mesuré en secondes) serait plus élevé que la valeur définie.

L’optimisation réalisée par SQL, bien qu’efficace pour les requêtes “volumineuses”, peut se révéler désastreuse pour l’exécution concurrente d’un grand nombre de petites requêtes, il est donc judicieux de revoir la valeur de ce paramètre en fonction du type de charge exercée sur le serveur SQL.

En règle générale, une valeur comprise entre 20 et 50 est un bon début qui doit être affiné par des tests spécifiques à l’application.

Par défaut, la valeur du paramètre “Count Threshold for Parallelism” est de 5, cette valeur provient du temps nécessaire à l’exécution d’une requête sur le poste de “Nick” un employé de Microsoft membre de l’équipe Query Optimizer lorsque le Query Optimizer était en cours de développement pour SQL Server 7.

Nick devait – entre autre – développer la méthode de calcul du coût d’une requête, il a donc utilisé son ordinateur comme étalon, depuis, le coût d’exécution d’une requête estimé par SQL est….le temps d’exécution qu'aurais pris la machine de Nick.

Bien entendu, les machines utilisées ne sont plus les mêmes et les temps d’exécutions sont donc plus courts :

image

La machine de Nick.

SQL Server ignore la valeur de l'option cost threshold for parallelism dans les cas suivants :

  • L'ordinateur ne dispose que d'un seul processeur.
  • Un seul UC est disponible pour SQL Server en raison de l'option de configuration affinity mask.
  • L'option max degree of parallelism a la valeur 1.

 

Réalisation

Le paramètre Count Threshold for Parallelism peut être modifié depuis les propriétés de l’instance SQL concernée dans la partie Advanced->Parallelism :

image

Ou via la requête suivante (en remplaçant VALEUR par la valeur désirée) :

sp_configure 'show advanced options', 1;
GO
reconfigure;
GO
sp_configure 'cost threshold for parallelism', VALEUR;
GO
reconfigure;
GO

La modification du paramètre Count Threshold for Parallelism est prise en compte sans qu’il n’y a à redémarrer l’instance.

Sources :

SQL Server–Rapport de découverte (Discovery Report)

Introduction

Le rapport de découverte SQL Server est utile afin de lister toutes les informations relatives à aux composants installés sur votre serveur SQL, leur version et leur édition.

L’objectif de ce post est de générer un rapport en mode GUI et en via un script.

Réalisation

  • En mode GUI :

Exécuter “SQL Server Installation Center :

image

Aller dans l’onglet “Tool” et cliquer sur “Installed SQL Server features discovery report” :

image

Le rapport de découverte SQL Server est enregistré dans “C:\Program Files\Microsoft SQL Server\VERSION\Setup Bootstrap\Log\AAAAMMDD_XXXXX

  • En mode script :

Depuis un invite de commande, exécuter la commande suivante: “Setup.exe /q /Action=RunDiscovery” depuis le répertoire “C:\Program Files\Microsoft SQL Server\VERSION\Setup Bootstrap\SQLServer2012”

image

Sources

SCOM – Script Mode Maintenance des Health Service Watcher

Lors du basculement d’agents gérés par une gateway vers une gateway de secours (failover), il peut arriver que quelques alertes “Heartbeat Failure” indésirables soit générées.

Le script suivant propose de lister, démarrer  ou arrêter les modes maintenance des instances Health Service Watcher des agents gérés par une gateway/management server donné.

Cette action est bien entendu possible pour une autre classe, dans la mesure ou le DisplayName  de l’instance correspond a celui de l’agent.

 

 

########################################################################################################################################### ## SCRIPT TO START/STOP/DISPLAY MAINTENANCE MODE FOR HEALTH SERVICE WATCHER OBJECTS THAT DEPENDS FROM SPECIFIC MANAGEMENT SERVER OR GATEWAY ## Author: CJOURDAN ########################################################################################################################################### #Parameters # $MGroup : Management Group to connect to # $MStoConnect : Management server to connect to # $PrimMS : Management server or Gateway FQDN from which depend agents. # $Reason : Reason for Maintenance Mode (Valid Reason are: PlannedOther # UnPlannedOther # PlannedHardwareMaintenance # UnplannedHardwareMaintenance # PlannedHardwareInstallation # UnplannedHardwareInstallation # PlannedOperatingSystemReconfiguration # UnplannedOperatingSystemReconfiguration # PlannedApplicationMaintenance # ApplicationInstallation # ApplicationUnresponsive # ApplicationUnstable # SecurityIssue # LossOfNetworkConnectivity) # # $Comment : Comment for Maintenance Mode # $MMAction : START or STOP OR DISPLAY Maintenance Mode # $MMDuration : Maintenance Mode Duration in minutes (only valuable for START $MMAction) # EXAMPLES: # Display Health Service Watcher Maintenance Mode Status for agents primary managed by MyPriMaryMS.mydomain.home # .\ScomSwitchMM.ps1 -MGroup MyMGROUP -MStoConnect MyMS.mydomain.home -PrimMS MyPriMaryMS.mydomain.home -MMAction display # Start Health Service Watcher Maintenance Mode for agents primary managed by MyPriMaryMS.mydomain.home during 60 min # .\ScomSwitchMM.ps1 -MGroup MyMGROUP -MStoConnect MyMS.mydomain.home -PrimMS MyPriMaryMS.mydomain.home -MMAction start -MMDuration 60 Param( [Parameter(Mandatory=$false)] $ClassName = "Health Service Watcher", [Parameter(Mandatory=$false)] $MGroup = "MyMGROUP", [Parameter(Mandatory=$false)] $MStoConnect= "MyMS.mydomain.home", [Parameter(Mandatory=$true)] $PrimMS= "MyPriMaryMS.mydomain.home", [Parameter(Mandatory=$false)] $Reason = "PlannedOther", [Parameter(Mandatory=$false)] $Comment = "", [Parameter(Mandatory=$true)] $MMAction = $(Read-Host -Prompt "PROVIDE TYPE OF MAINTENANCE MODE ACTION: START or STOP OR DISPLAY"), [Parameter(Mandatory=$false)] # $MMDuration in minutes $MMDuration = 0 ) if ($MMAction -notmatch ".*STOP.*|.*START.*|.*DISPLAY.*") { write-host -ForegroundColor Yellow "YOU MUST PROVIDE VALID MAINTENANCE MODE ACTION TYPE: START or STOP or DISPLAY" EXIT 1 } $cred = $(Get-Credential -Credential "MyDomain\") #Import du module SCOM try { Import-Module -Name OperationsManager -ErrorAction stop } catch { write-host -ForegroundColor red "Error during import of SCOM PS Module" EXIT 1 } #Connection au management group $MGroup try { New-SCOMManagementGroupConnection -ComputerName $MStoConnect -Credential $cred } catch { write-host -ForegroundColor red "Error during connection to MS $MStoConnect - CHECK CREDENTIALS USED" EXIT 1 } # Get Scom agents that have $PrimMS as Primary Management Server $agents = get-scomagent | where {$_.PrimaryManagementServerName -eq $PrimMS} if (!($agents)) { write-host "NO SCOM AGENTS FOUND FOR SERVER $PrimMS - CHECK THAT THE NAME IS CORRECT (YOU MUST PROVIDE FQDN) OR THAT THIS SERVER BELONG TO $MGroup MANAGEMENT GROUP" EXIT 1 } # Get "Health Service Watcher" Class Instances $class = Get-SCOMClass -DisplayName $ClassName switch($MMAction) { START { # Get instances of "Health Service Watcher" Class $ClassInstances = Get-SCOMClassInstance -Class $class # Class to put in MM Table $ClassInstToMM = @() # Get class instances that match agents foreach ($agent in $agents) { $ClassInstToMM += ($ClassInstances | Where-Object {$_.DisplayName -eq $agent.displayname}) } $starttime = $(get-date).ToUniversalTime() $endtime = $(get-date).AddMinutes($MMDuration).ToUniversalTime() # PUT IN Maintenance Mode $($ClassInstToMM | foreach {$_.schedulemaintenancemode($starttime,$endtime,$Reason,$Comment)}) # Display effective instances in MM write-host "EFFECTIVE INSTANCES OF CLASS '$ClassName' IN MAINTENANCE MODE (Primary Managed by $PrimMS):" # Get instances of "Health Service Watcher" Class $ClassInstances = Get-SCOMClassInstance -Class $class $ClassInstInMM = @() # Get class instances that match agents foreach ($agent in $agents) { $ClassInstInMM += ($ClassInstances | Where-Object {$_.DisplayName -eq $agent.displayname}) } $ClassInstInMM } STOP { # Get instances of "Health Service Watcher" Class $ClassInstances = Get-SCOMClassInstance -Class $class # Class to put out of MM Table $ClassInstOoMM = @() # Get class instances that match agents foreach ($agent in $agents) { $ClassInstOoMM += ($ClassInstances | Where-Object {$_.DisplayName -eq $agent.displayname}) } # Only Endttime in necessary and it is now $endtime = $(get-date).ToUniversalTime() # PUT IN Maintenance Mode $($ClassInstOoMM | foreach {$_.stopmaintenancemode($endtime)}) # Display effective instances in MM write-host "EFFECTIVE INSTANCES OF CLASS '$ClassName' OUT OF MAINTENANCE MODE (Primary Managed by $PrimMS):" # Get instances of "Health Service Watcher" Class $ClassInstances = Get-SCOMClassInstance -Class $class $ClassInstOoMM = @() # Get class instances that match agents foreach ($agent in $agents) { $ClassInstOoMM += ($ClassInstances | Where-Object {$_.DisplayName -eq $agent.displayname}) } $ClassInstOoMM } DISPLAY { # Display effective instances in MM write-host "`n INSTANCES OF CLASS '$ClassName' MAINTENANCE MODE STATE (Primary Managed by $PrimMS):" # Get instances of "Health Service Watcher" Class $ClassInstances = Get-SCOMClassInstance -Class $class $ClassInstMM = @() # Get class instances that match agents foreach ($agent in $agents) { $ClassInstMM += ($ClassInstances | Where-Object {$_.DisplayName -eq $agent.displayname}) } $ClassInstMM } }

Authentification SSO avec l'ADFS et Apache 2.5 (installé sur un windows)

Sur mon blog précédent : https://blog.piservices.fr/post/2017/04/28/authentification-sso-avec-l-adfs-et-apache-2-5-installe-sur-un-linux , j'ai expliqué comment configurer un serveur apache installé sur un linux pour faire du SSO avec l'adfs en utilisant auth_mellon et lasso. Aujourd'hui nous allons voir la même chose mais sur un apache installé sur un Windows. 

Contexte

Apache ne communique pas nativement avec l'ADFS. Pour permettre à des applications web qui tournent sur apache de faire de l'authentification SSO, il faudrait installer SimpleSAMLphp qui contient tous les modules nécessaire pour faire du SAML.

Installation du simpleSAMLphp

1. Depuis le site télécharger la dernière version stable de SimpleSAMLphp. Décompression le fichier et déplacer les contenus dans le répertoire www du serveur apache.

2. Accèder au dossier www\simplesamlphp-1.14.11\www\index.php depuis votre navigateur et une page d'installation et de configuration de SimpleSAMLphp apparaîtra. 

Sélectionner >Configuration et vous verrez que par défaut le protocole SAML 2.0 - Idp est désactivé:

Pour l'activer aller dans le fichier \simplesamlphp-1.14.11\config\config.php et modifier le paramètre 'enable.saml20-idp' en true: 

/*
     * Enable
     *
     * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only
     * one of the functionalities below, but in some cases you could run multiple functionalities.
     * In example when you are setting up a federation bridge.
     */
    'enable.saml20-idp' => true,
    'enable.shib13-idp' => false,
    'enable.adfs-idp' => false,
    'enable.wsfed-sp' => false,
    'enable.authmemcookie' => false,

Faire un refresh de la page:

Note: Dans notre cas l'idp est un ADFS donc pas besoin d'activer l'idp sur le serveur apache.

S'assurer que tous les prérequis nécessaires sont installés depuis la page configuration:

3. Créer le certificat SSL (auto-signé) pour le service provider (SP) avec openssl (assurez vous que openssl est installé)

openssl req -new -x509 -days 3652 -nodes -out saml.crt -keyout saml.pem

et entrer les fichiers *.crt et *.pem dans le fichier de configuration \simplesamlphp-1.14.11\config\authsources.php comme indiqué ci-dessous:

    // An authentication source which can authenticate against both SAML 2.0
    // and Shibboleth 1.3 IdPs.
    'default-sp' => array(
        'saml:SP',

        // The entity ID of this SP.
        // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.
        'entityID' => 'http://testapplication/',

        // The entity ID of the IdP this should SP should contact.
        // Can be NULL/unset, in which case the user will be shown a list of available IdPs.
        'idp' => 'https://fs.xxx-xxx.com/federationmetadata/2007-06/federationmetadata.xml',

        // The URL to the discovery service.
        // Can be NULL/unset, in which case a builtin discovery service will be used.
        'discoURL' => null,
		'privatekey' => 'saml.pem',
        'certificate' => 'saml.crt',
  • entityID = l'url de l'application web
  • idp = l'url ou le fichier metadata de l'identity provider (l'idp)
  • privatekey = le fcihier pem créé précédemment
  • certificate = le ficher crt créé précédemment

Génération du fichier service provider (SP) metadata.

Il faudra par la suite générer le fichier metadata du service provider (sp) et l'utiliser pour configuration la fédération ADFS.

Pour générer le fichier sp metadat aller dans sur la page Féderation et cliquer sur [Afficher les métadonnées] de SP SAML 2.0

Une page avec les métadonnées apparaîtra, sauvegarder les tous dans un fichier au format xml. Exemple d'un fichier de metadonnées généré par SimpleSAMLphp:

<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://testapplication/">
  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol">
    <md:KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIIEFTCCAv2gAwIBAgIJALEBPyeEV48BMA0GCSqGSIb3DQEBCwUAMIGgMQswCQYDVQQGEwJGUjEMMAoGA1UECAwDSURGMQ4wDAYDVQQHDAVQQVJJUzEUMBIGA1UECgwLQVBQTElDQVRJT04xGzAZBgNVBAsMEkFQUExJQ0FUSU9OIEdST1VQRTEVMBMGA1UEAwwMQVBQTElDQVRJT04xMSkwJwYJKoZIhvcNAQkBFhptZXZlbi5rYXJ1cHBhbm5hbkBsaXZlLmNvbTAeFw0xNzAyMDgxMTI3MjJaFw0yNzAyMDgxMTI3MjJaMIGgMQswCQYDVQQGEwJGUjEMMAoGA1UECAwDSURGMQ4wDAYDVQQHDAVQQVJJUzEUMBIGA1UECgwLQVBQTElDQVRJT04xGzAZBgNVBAsMEkFQUExJQ0FUSU9OIEdST1VQRTEVMBMGA1UEAwwMQVBQTElDQVRJT04xMSkwJwYJKoZIhvcNAQkBFhptZXZlbi5rYXJ1cHBhbm5hbkBsaXZlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALjKwVm4GtahFeBZXataYQzIWIAqcenA4RjmyGaGnI64uttEXDea8qpY+FYYCG9QIJWksz9CBrmM81bCi63DvQMa/ufGhTR6x99I5XHXdzya2F0DZCG6VuruPzLFuxi7u3p/ViHzmFkdEW9Gv23+s/SNyXnO7w4+YHiazobTadH9OmioPxd9m9Llwiml0I7FeVkfcnmscNOezD0P89eWVKkRnOjH8yccp2skke1nbHAv7Kh37dt3tq8uE/QPxC9gWimgyuJdo8F49RL6b2vE5laAxKYUSCjY6bcMg2MXrTiJMKmnqj0POauS8r9jy7V26+6sGtjNajOerem2X7ShskkCAwEAAaNQME4wHQYDVR0OBBYEFNB6YexsAR7Hy1YRDN54MxBdId5YMB8GA1UdIwQYMBaAFNB6YexsAR7Hy1YRDN54MxBdId5YMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAG1hkGrJcNCrhmacqKi6sOV05238ix0ynGhtZyHVmIZf2OmJIXj117Xk9SHcCk4pFx26yfHOH4vnqK579UL1ACg1bp21R1POO4GNnhXRQiPwOdhtCOprYt9vq1zP7+aIiU4v6gSDUAcWf7a6nin4dwcYfO0cHAly7TW75tJGQa88eT9/v4s7YIopm+8D/+8skB8HqbkJ7i5E6+iILdHXgKqj1amxojPYjrH5ZFZmxS+tT5Z33+PU+FMwYw5YzmSAV84QfotZamcIc95A7FUNP2VEQjkX3nx6zuY+RE8aZr6Ul2ORPJVrnajrcUooP8f6Rd70Fg2Eaq/gmK1bP6UOm4=</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
          <ds:X509Certificate>MIIEFTCCAv2gAwIBAgIJALEBPyeEV48BMA0GCSqGSIb3DQEBCwUAMIGgMQswCQYDVQQGEwJGUjEMMAoGA1UECAwDSURGMQ4wDAYDVQQHDAVQQVJJUzEUMBIGA1UECgwLQVBQTElDQVRJT04xGzAZBgNVBAsMEkFQUExJQ0FUSU9OIEdST1VQRTEVMBMGA1UEAwwMQVBQTElDQVRJT04xMSkwJwYJKoZIhvcNAQkBFhptZXZlbi5rYXJ1cHBhbm5hbkBsaXZlLmNvbTAeFw0xNzAyMDgxMTI3MjJaFw0yNzAyMDgxMTI3MjJaMIGgMQswCQYDVQQGEwJGUjEMMAoGA1UECAwDSURGMQ4wDAYDVQQHDAVQQVJJUzEUMBIGA1UECgwLQVBQTElDQVRJT04xGzAZBgNVBAsMEkFQUExJQ0FUSU9OIEdST1VQRTEVMBMGA1UEAwwMQVBQTElDQVRJT04xMSkwJwYJKoZIhvcNAQkBFhptZXZlbi5rYXJ1cHBhbm5hbkBsaXZlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALjKwVm4GtahFeBZXataYQzIWIAqcenA4RjmyGaGnI64uttEXDea8qpY+FYYCG9QIJWksz9CBrmM81bCi63DvQMa/ufGhTR6x99I5XHXdzya2F0DZCG6VuruPzLFuxi7u3p/ViHzmFkdEW9Gv23+s/SNyXnO7w4+YHiazobTadH9OmioPxd9m9Llwiml0I7FeVkfcnmscNOezD0P89eWVKkRnOjH8yccp2skke1nbHAv7Kh37dt3tq8uE/QPxC9gWimgyuJdo8F49RL6b2vE5laAxKYUSCjY6bcMg2MXrTiJMKmnqj0POauS8r9jy7V26+6sGtjNajOerem2X7ShskkCAwEAAaNQME4wHQYDVR0OBBYEFNB6YexsAR7Hy1YRDN54MxBdId5YMB8GA1UdIwQYMBaAFNB6YexsAR7Hy1YRDN54MxBdId5YMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAG1hkGrJcNCrhmacqKi6sOV05238ix0ynGhtZyHVmIZf2OmJIXj117Xk9SHcCk4pFx26yfHOH4vnqK579UL1ACg1bp21R1POO4GNnhXRQiPwOdhtCOprYt9vq1zP7+aIiU4v6gSDUAcWf7a6nin4dwcYfO0cHAly7TW75tJGQa88eT9/v4s7YIopm+8D/+8skB8HqbkJ7i5E6+iILdHXgKqj1amxojPYjrH5ZFZmxS+tT5Z33+PU+FMwYw5YzmSAV84QfotZamcIc95A7FUNP2VEQjkX3nx6zuY+RE8aZr6Ul2ORPJVrnajrcUooP8f6Rd70Fg2Eaq/gmK1bP6UOm4=</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" index="0"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="http://localhost/simplesaml/module.php/saml/sp/saml1-acs.php/default-sp" index="1"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" index="2"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="http://localhost/simplesaml/module.php/saml/sp/saml1-acs.php/default-sp/artifact" index="3"/>
  </md:SPSSODescriptor>
</md:EntityDescriptor>

Maintenant il ne reste plus qu'à configuration l'ADFS avec le fichier métadonnées du SP et faire un test. Pour effectuer un test et voir si l'authentification fontionne bien , aller sur la page [Authentifcation] et sélectionner [Tester les sources d'authentification configurées]

Pour accéder à cette page , connecter vous en tant qu'administrateur. Le mot de passe du compte administration est configuration depuis le fichier www\simplesamlphp-1.14.11\config\config.php avec le paramètre 'auth.adminpassword'

/**
     * This password must be kept secret, and modified from the default value 123.
     * This password will give access to the installation page of SimpleSAMLphp with
     * metadata listing and diagnostics pages.
     * You can also put a hash here; run "bin/pwgen.php" to generate one.
     */
    'auth.adminpassword' => '1234',
    'admin.protectindexpage' => false,
    'admin.protectmetadata' => false,