Partager via


Déboguer les erreurs d’authentification Windows

Lorsque vous utilisez l’authentification Windows comme mécanisme de sécurité, l’interface du fournisseur de support de sécurité (SSPI) gère les processus de sécurité. Lorsque des erreurs de sécurité se produisent au niveau de la couche SSPI, elles sont exposées par Windows Communication Foundation (WCF). Cette rubrique fournit une infrastructure et un ensemble de questions pour aider à diagnostiquer les erreurs.

Pour obtenir une vue d’ensemble du protocole Kerberos, consultez Kerberos Expliqué ; pour obtenir une vue d’ensemble de SSPI, consultez SSPI.

Pour l’authentification Windows, WCF utilise généralement le fournisseur SSP ( Negotiate Security Support Provider), qui effectue l’authentification mutuelle Kerberos entre le client et le service. Si le protocole Kerberos n’est pas disponible, par défaut, WCF revient au Gestionnaire NT LAN (NTLM). 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 sûr 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 approprié.

Disponibilité du protocole Kerberos et de NTLM

Le fournisseur de services partagés Kerberos nécessite qu’un contrôleur de domaine agisse comme centre de distribution de clés Kerberos (KDC). Le protocole Kerberos est disponible uniquement lorsque le client et le service utilisent des identités de domaine. Dans d’autres combinaisons de comptes, NTLM est utilisé, comme résumé dans le tableau suivant.

Les en-têtes de tableau affichent les types de comptes possibles utilisés par le serveur. La colonne de gauche affiche les types de comptes 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 sont les suivants :

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

  • Système local : le système de compte intégré sur un ordinateur qui n’est pas joint à un domaine.

  • Utilisateur de domaine : un 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.

Remarque

Les informations d’identification du service sont capturées lorsque la Open méthode de la ServiceHost classe 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 décrit certains problèmes d’authentification Windows courants et les solutions possibles.

Protocole Kerberos

Problèmes spn/UPN avec le protocole Kerberos

Lorsque 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 à l’intérieur de l’URL du service. Cela suppose que le compte sous lequel le service s’exécute a accès à la clé de nom de principal de service (SPN) de l’ordinateur (par défaut) créée lorsque l’ordinateur est ajouté au domaine Active Directory, ce qui est le plus souvent effectué en exécutant le service sous le compte de service réseau. Si le service n’a pas accès à la clé SPN de l’ordinateur, vous devez fournir le nom de principal d’utilisateur (UPN) correct du compte sous lequel le service s’exécute dans l’identité du point de terminaison du client. Pour plus d’informations sur le fonctionnement de WCF avec SPN et UPN, consultez Service Identity and Authentication.

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, à affecter un SPN à ce compte et à garantir que tous les services de l’application s’exécutent dans 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 Le supplément technique Kerberos pour Windows.

Le protocole Kerberos direct nécessite que le service s’exécute sous un compte d’ordinateur de domaine

Cela se produit lorsque la propriété ClientCredentialType est définie sur Windows et que la propriété NegotiateServiceCredential est définie sur false, comme 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 remédier à ce problème, exécutez le service à l’aide d’un compte d’ordinateur de domaine, tel que le service réseau, sur un ordinateur joint à un 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 négociation des certificats (parfois appelé « multi-phase » ou « multi-étapes » Kerberos). 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 des identifiants, procédez comme suit :

  1. Implémenter la délégation en définissant AllowedImpersonationLevel sur Delegation.

  2. Requérez la négociation SSPI :

    1. Si vous utilisez des liaisons standard, définissez la NegotiateServiceCredential propriété sur true.

    2. Si vous utilisez des liaisons personnalisées, définissez l’attribut AuthenticationMode de l’élément Security sur SspiNegotiated.

  3. Exiger la négociation SSPI pour utiliser Kerberos en supprimant l’utilisation de NTLM :

    1. Effectuez cette opération dans le code, avec l’instruction suivante : ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. Vous pouvez également le faire dans le fichier de configuration en définissant l’attribut allowNtlm sur false. Cet attribut est contenu dans les <fenêtres>.

Protocole NTLM

Negotiate SSP revient à NTLM, mais NTLM est désactivé

La propriété AllowNtlm est définie sur false, ce qui amène Windows Communication Foundation (WCF) à tenter de lever une exception si NTLM est utilisé. La définition de cette propriété false peut ne pas empêcher l’envoi d’informations d’identification NTLM sur le câble.

L’exemple suivant montre comment désactiver le recours à 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 de 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. Bien que les informations d’identification soient valides sur l’ordinateur où le client s'exécute, cette ouverture de session échouera si elles ne sont pas valides sur l’ordinateur du service.

Une connexion NTLM anonyme se produit, mais les connexions anonymes sont désactivées par défaut.

Lors de la création d’un client, la propriété AllowedImpersonationLevel est définie sur Anonymous, comme illustré dans l’exemple suivant, mais par défaut, le serveur interdit les connexions anonymes. Cela se produit parce que la valeur par défaut de la AllowAnonymousLogons propriété de la WindowsServiceCredential classe est false.

Le code client suivant tente d’activer les connexions anonymes (à noter 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 pour permettre les connexions anonymes au 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’usurpation d’identité, consultez Délégation et usurpation d’identité.

Vous pouvez également exécuter le client en tant que service Windows à l’aide du système de compte intégré.

Autres problèmes

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

L’authentification Windows utilise l’instance WindowsClientCredential retournée par la ClientCredentials propriété de la ClientBase<TChannel> classe, et non par le UserNamePasswordClientCredential. L’exemple suivant montre 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!

Voici 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’ils sont utilisés en tant que serveur : Windows XP Home Edition, Windows XP Media Center Edition et Windows Vista Home éditions.

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

Si vous développez votre application sur un ordinateur et que vous déployez sur un autre et utilisez différents types de comptes pour vous authentifier sur chaque ordinateur, vous pouvez rencontrer un comportement différent. Par exemple, supposons que vous développez votre application sur un ordinateur Windows XP Pro à l’aide du SSPI Negotiated mode d’authentification. Si vous utilisez un compte d’utilisateur local pour vous authentifier avec, le protocole NTLM sera utilisé. Une fois l’application 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 pourra pas authentifier le service, car il utilisera Kerberos et un contrôleur de domaine.

Voir aussi