Déboguer les erreurs de l’authentification Windows

Lorsque vous utilisez l'authentification Windows comme un mécanisme de sécurité, l'interface SSPI (Security Support Provider Interface) gère les processus de sécurité. Lorsque des erreurs de sécurité se produisent au niveau de la couche SSPI, elles sont signalées par Windows Communication Foundation (WCF). Cette rubrique fournit une infrastructure et un ensemble de questions permettant de diagnostiquer les erreurs.

Pour obtenir une vue d’ensemble du protocole Kerberos, consultez Présentation de Kerberos. Pour obtenir une vue d’ensemble de SSPI, consultez SSPI.

Pour l’authentification Windows, WCF utilise généralement le fournisseur SSP (Security Support Provider) Negotiate, qui exécute l’authentification mutuelle Kerberos entre le client et le service. Si le protocole Kerberos n’est pas disponible, WCF revient par défaut à NTLM (NT LAN Manager). Toutefois, vous pouvez configurer WCF pour utiliser uniquement le protocole Kerberos (et lever une exception si Kerberos n’est pas disponible). Vous pouvez également configurer WCF pour utiliser des formes restreintes du protocole Kerberos.

Méthodologie de débogage

La méthode de base est la suivante :

  1. Déterminez si vous utilisez l'authentification Windows. Si vous utilisez un autre schéma, cette rubrique ne s'applique pas.

  2. Si vous êtes certain d’utiliser l’authentification Windows, déterminez si votre configuration WCF utilise Kerberos direct ou Negotiate.

  3. Une fois que vous avez déterminé si votre configuration utilise le protocole Kerberos ou NTLM, vous pouvez comprendre les messages d'erreur dans le contexte correct.

Disponibilité du protocole Kerberos et de NTLM

Le fournisseur SSP Kerberos requiert qu'un contrôleur de domaine se comporte comme un centre de distribution de clés (KDC, Key Distribution Center). Le protocole Kerberos est disponible uniquement lorsque le client et le service utilisent des identités de domaine. NTLM est utilisé dans d'autres combinaisons de comptes, tel qu'indiqué dans le tableau suivant.

Les en-têtes du tableau présentent les types de compte possibles utilisés par le serveur. La colonne de gauche présente les types de compte possibles utilisés par le client.

Utilisateur local Système Local Utilisateur de domaine Ordinateur de domaine
Utilisateur local NTLM NTLM NTLM NTLM
Système local NTLM anonyme NTLM anonyme NTLM anonyme NTLM anonyme
Utilisateur de domaine NTLM NTLM Kerberos Kerberos
Ordinateur de domaine NTLM NTLM Kerberos Kerberos

Plus précisément, les quatre types de comptes incluent :

  • Utilisateur local : profil utilisateur, ordinateur uniquement. Par exemple, MachineName\Administrator ou MachineName\ProfileName.

  • Système local : compte intégré SYSTEM sur un ordinateur qui n'est pas joint à un domaine.

  • Utilisateur de domaine : compte d'utilisateur sur un domaine Windows. Par exemple : DomainName\ProfileName.

  • Ordinateur de domaine : processus avec identité d'ordinateur s'exécutant sur un ordinateur joint à un domaine Windows. Par exemple : MachineName\Network Service.

Notes

Les informations d'identification du service sont capturées lorsque la méthode Open de la classe ServiceHost est appelée. Les informations d'identification du client sont lues chaque fois que le client envoie un message.

Problèmes courants d'authentification Windows

Cette section présente certains problèmes d'authentification Windows courants et les solutions possibles.

Protocole Kerberos

Problèmes de SPN/UPN rencontrés avec le protocole Kerberos

Si vous utilisez l'authentification Windows, et que le protocole Kerberos est utilisé ou négocié par SSPI, l'URL utilisée par le point de terminaison client doit inclure le nom de domaine complet de l'hôte du service dans l'URL de service. Cela suppose que le compte sous lequel le service s'exécute a accès à la clé SPN (Service Principal Name) par défaut de l'ordinateur créée lorsque celui-ci est ajouté au domaine Active Directory, ce qui s'effectue le plus souvent en exécutant le service sous le compte Service Réseau. Si le service n'a pas accès à la clé SPN de l'ordinateur, vous devez fournir le SPN correct ou un nom d'utilisateur principal (UPN, User Principal Name) du compte sous lequel le service s'exécute dans l'identité de point de terminaison du client. Pour plus d’informations sur le fonctionnement de WCF avec SPN et UPN, consultez Identité et authentification du service.

Dans les scénarios d'équilibrage de charge, tels que les batteries de serveurs Web ou les jardins Web, une pratique courante consiste à définir un compte unique pour chaque application, assigner un SPN à ce compte et veiller à ce que tous les services de l'application s'exécutent sous ce compte.

Pour obtenir un SPN pour le compte de votre service, vous devez être administrateur de domaine Active Directory. Pour plus d’informations, consultez Supplément technique Kerberos pour Windows.

Le protocole Kerberos direct requiert l'exécution du service sous un compte d'ordinateur de domaine

Cela se produit lorsque la propriété ClientCredentialType a la valeur Windows et que la propriété NegotiateServiceCredential a la valeur false, tel qu'indiqué dans le code suivant.

WSHttpBinding b = new WSHttpBinding();
// By default, the WSHttpBinding uses Windows authentication
// and Message mode.
b.Security.Message.NegotiateServiceCredential = false;
Dim b As New WSHttpBinding()
' By default, the WSHttpBinding uses Windows authentication 
' and Message mode.
b.Security.Message.NegotiateServiceCredential = False

Pour y remédier, exécutez le service à l'aide d'un compte d'ordinateur de domaine, tel que Service réseau, sur un ordinateur joint au domaine.

La délégation nécessite la négociation des informations d'identification

Pour utiliser le protocole d'authentification Kerberos avec délégation, vous devez implémenter le protocole Kerberos avec la négociation d'informations d'identification (parfois appelé Kerberos « multi-leg » ou Kerberos « multi-step »). Si vous implémentez l'authentification Kerberos sans négociation d'informations d'identification (parfois appelée Kerberos « one-shot » ou Kerberos « single-leg »), une exception sera levée.

Pour implémenter Kerberos avec la négociation d'information d'identification, procédez comme suit :

  1. Implémentez la délégation en affectant AllowedImpersonationLevel à Delegation.

  2. Requérez la négociation SSPI :

    1. Si vous utilisez des liaisons standard, affectez NegotiateServiceCredential à la propriété true.

    2. Si vous utilisez des liaisons personnalisées, affectez AuthenticationMode à l’attribut Security de l’élément SspiNegotiated.

  3. Requérez que la négociation SSPI utilise Kerberos en interdisant l'utilisation de NTLM :

    1. Effectuez cette opération dans le code, à l'aide de l'instruction suivante : ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. Vous pouvez également effectuer cette opération dans le fichier de configuration en affectant allowNtlm à l'attribut false. Cet attribut est contenu dans <windows>.

Protocole NTLM

Négociation du retour de SSP à NTLM, mais NTLM est désactivé

La propriété AllowNtlm est définie sur false, ce qui conduit Windows Communication Foundation (WCF) à faire au mieux pour lever une exception si NTLM est utilisé. L’affectation de la valeur false à cette propriété peut ne pas empêcher la transmission des informations d’identification NTLM sur le réseau.

La section suivante indique comment désactiver le retour à NTLM.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowNtlm = False

Échec d'ouverture de session NTLM

Les informations d'identification du client ne sont pas valides sur le service. Vérifiez que le nom d'utilisateur et le mot de passe sont correctement définis et correspondent à un compte connu sur l'ordinateur sur lequel le service s'exécute. NTLM utilise les informations d'identification spécifiées pour se connecter à l'ordinateur du service. Même si les informations d'identification sont valides sur l'ordinateur sur lequel le client s'exécute, cette ouverture de session échouera si elles ne sont pas valides sur l'ordinateur du service.

Une ouverture de session NTLM anonyme se produit, mais les ouvertures de session anonymes sont désactivées par défaut

Lors de la création d'un client, la propriété AllowedImpersonationLevel a la valeur Anonymous, tel qu'indiqué dans l'exemple suivant, mais par défaut, le serveur interdit les ouvertures de session anonymes. En effet, la valeur par défaut de la propriété AllowAnonymousLogons de la classe WindowsServiceCredential est false.

Le code client suivant tente d'activer des ouvertures de session anonymes (notez que la propriété par défaut est Identification).

CalculatorClient cc =
    new CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Anonymous;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Anonymous

Le code de service suivant modifie la valeur par défaut afin d'activer des ouvertures de session anonymes par le serveur.

Uri httpUri = new Uri("http://localhost:8000/");
ServiceHost sh = new ServiceHost(typeof(Calculator), httpUri);
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = true;
Dim httpUri As New Uri("http://localhost:8000/")
Dim sh As New ServiceHost(GetType(Calculator), httpUri)
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = True

Pour plus d’informations sur l’emprunt d’identité, consultez Délégation et emprunt d’identité.

Le client s'exécute également en tant que service Windows, à l'aide du compte intégré SYSTEM.

Autres problèmes

Les informations d'identification du client ne sont pas correctement définies

L'authentification Windows utilise l'instance WindowsClientCredential retournée par la propriété ClientCredentials de la classe ClientBase<TChannel>, et non pas UserNamePasswordClientCredential. Le code suivant présente un exemple incorrect.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.UserName.UserName = GetUserName(); // wrong!
cc.ClientCredentials.UserName.Password = GetPassword(); // wrong!
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.UserName.UserName = GetUserName() ' wrong!
cc.ClientCredentials.UserName.Password = GetPassword() ' wrong!

Le code suivant présente l'exemple correct.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
// This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName();
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword();
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
' This code returns the WindowsClientCredential type.            
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName()
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword()

SSPI n'est pas disponible

Les systèmes d’exploitation suivants ne prennent pas en charge l’authentification Windows lorsqu’elle est utilisée en tant que serveur : Windows XP Édition familiale, Windows XP Édition Media Center et Windows Vista Édition familiale.

Développement et déploiement avec des identités différentes

Si vous développez votre application sur un ordinateur, la déployez sur un autre et utilisez différents types de compte pour vous authentifier sur chaque ordinateur, vous pouvez observer un comportement différent. Par exemple, supposons que vous développiez votre application sur un ordinateur Windows XP Professionnel à l’aide du mode d’authentification SSPI Negotiated. Si vous utilisez un compte d'utilisateur local pour vous authentifier, le protocole NTLM sera alors utilisé. Une fois que l'application est développée, vous déployez le service sur un ordinateur Windows Server 2003 où il s'exécute sous un compte de domaine. À ce stade, le client ne sera pas en mesure d’authentifier le service car il utilisera Kerberos et un contrôleur de domaine.

Voir aussi