Eseguire il debug degli errori di autenticazione di Windows

Quando si utilizza l'autenticazione di Windows come meccanismo di sicurezza, i processi di sicurezza vengono gestiti dall'interfaccia SSPI (Security Support Provider Interface). Quando si verificano errori di sicurezza a livello SSPI, vengono visualizzati da Windows Communication Foundation (WCF). In questo argomento viene fornito un framework e un insieme di domande per facilitare la diagnosi degli errori.

Per una panoramica del protocollo Kerberos, vedere Kerberos Explained; per una panoramica di SSPI, vedere SSPI.

Per l'autenticazione di Windows, in WCF viene in genere usato Security Support Provider (SSP) negoziato, che esegue l'autenticazione reciproca Kerberos tra il client e il servizio. Se il protocollo Kerberos non è disponibile, per impostazione predefinita, WCF esegue il fallback al protocollo NTLM (NT LAN Manager). È tuttavia possibile configurare WCF per usare solo il protocollo Kerberos e viene generata un'eccezione se Kerberos non è disponibile. È inoltre possibile configurare WCF per usare formati con restrizioni del protocollo Kerberos.

Metodologia di debug

Il metodo di base è il seguente:

  1. Determinare se si sta utilizzando l'autenticazione di Windows. Se si sta utilizzando qualsiasi altro schema, questo argomento non è applicabile.

  2. Se si sta usando con certezza l'autenticazione di Windows, determinare se la configurazione WCF usa Kerberos direttamente o Negotiate.

  3. Una volta determinato se la configurazione utilizza il protocollo Kerberos o NTLM, è possibile comprendere i messaggi di errore nel contesto giusto.

Disponibilità del protocollo Kerberos e NTLM

Per l'SSP Kerberos è necessario un controller di dominio che agisca da Centro di distribuzione chiave Kerberos (KDC, Kerberos Key Distribution Center). Il protocollo Kerberos è disponibile solo quando sia il client che il servizio utilizzano identità di dominio. In altre combinazioni di account, viene utilizzato il protocollo NTLM, come riepilogato nella tabella seguente.

Nelle intestazioni della tabella vengono riportati i possibili tipi di account utilizzati dal server, mentre nella colonna sinistra vengono indicati i possibili tipi di account utilizzati dal client.

Utente locale Local System (Sistema locale) Utente del dominio Computer del dominio
Utente locale NTLM NTLM NTLM NTLM
Sistema locale NTLM anonimo NTLM anonimo NTLM anonimo NTLM anonimo
Utente di dominio NTLM NTLM Kerberos Kerberos
Computer del dominio NTLM NTLM Kerberos Kerberos

In particolare, i quattro tipi di account includono:

  • Utente locale: profilo utente del computer. Ad esempio, MachineName\Administrator o MachineName\ProfileName.

  • Sistema locale: account predefinito SYSTEM in un computer non associato a un dominio.

  • Utente del dominio: account utente in un dominio Windows. Ad esempio: DomainName\ProfileName.

  • Computer del dominio: processo con identità di computer in esecuzione in un computer associato a un dominio Windows. Ad esempio: MachineName\Network Service.

Nota

La credenziale del servizio viene acquisita quando viene chiamato il metodo Open della classe ServiceHost. La credenziale del client viene letta ogni volta che il client invia un messaggio.

Problemi di autenticazione di Windows comuni

Contenuto della sezione vengono illustrati alcuni problemi di autenticazione di Windows comuni e le possibili soluzioni.

Protocollo Kerberos

Problemi SPN/UPN con il protocollo Kerberos

Quando si utilizza l'autenticazione di Windows unitamente al protocollo Kerberos diretto o negoziato mediante SSPI, l'URL utilizzato dall'endpoint client deve includere il nome di dominio completo dell'host del servizio presente nell'URL del servizio. Questo presuppone che l'account usato per l'esecuzione del servizio abbia accesso alla chiave del nome dell'entità servizio (SPN) del computer (impostazione predefinita) creata quando il computer viene aggiunto al dominio di Active Directory, generalmente eseguendo il servizio con l'account Servizio di rete. Se il servizio non ha accesso alla chiave dell'SPN del computer, è necessario fornire l'SPN corretto o il nome dell'entità utente (UPN) dell'account utilizzato per l'esecuzione del servizio nell'identità dell'endpoint del client. Per altre informazioni sul funzionamento di WCF con SPN e UPN, vedere Identità del servizio e autenticazione.

In scenari di bilanciamento del carico, ad esempio Web farm o Web garden, viene comunemente definito un account univoco per ogni applicazione, viene assegnato un SPN a tale account e viene verificato che tutti i servizi dell'applicazione siano eseguiti in tale account.

Per ottenere un SPN per l'account del servizio, è necessario essere amministratore di dominio di Active Directory. Per altre informazioni, vedere Supplemento tecnico Kerberos per Windows.

Per il protocollo Kerberos diretto è necessario che il servizio venga eseguito utilizzando un account di tipo computer del dominio

Questo si verifica quando la proprietà ClientCredentialType è impostata su Windows e la proprietà NegotiateServiceCredential è impostata su false, come illustrato nel codice seguente.

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

Per risolvere questo problema, eseguire il servizio utilizzando un account di tipo computer del dominio, ad esempio Servizio di rete, in un computer associato al dominio.

Requisito di negoziazione della credenziale in caso di delega

Per poter essere utilizzato con la funzionalità di delega, il protocollo di autenticazione Kerberos deve essere implementato con la negoziazione della credenziale. Questa versione di Kerberos è nota come Kerberos multifase o multipassaggio. Se si implementa l'autenticazione Kerberos senza negoziazione della credenziale (ovvero una versione di Kerberos anche nota come "monofase" o "monopassaggio), verrà generata un'eccezione.

Per implementare Kerberos con negoziazione della credenziale, eseguire le operazioni seguenti:

  1. Implementare la delega impostando AllowedImpersonationLevel su Delegation.

  2. Richiedere la negoziazione SSPI:

    1. Se si utilizzano associazioni standard, impostare la proprietà NegotiateServiceCredential su true.

    2. Se si utilizzano associazioni personalizzate, impostare l'attributo AuthenticationMode dell'elemento Security su SspiNegotiated.

  3. Richiedere che la negoziazione SSPI utilizzi Kerberos impedendo l'utilizzo di NTLM:

    1. È possibile eseguire questa operazione nel codice utilizzando l'istruzione seguente: ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. In alternativa, è possibile operare nel file di configurazione impostando l'attributo allowNtlm su false. Questo attributo è contenuto nelle <finestre>.

Protocollo NTLM

Il provider SSP Negotiate esegue il fallback a NTLM, ma NTLM è disabilitato

La proprietà AllowNtlm è impostata su false, che determina l'uso di Windows Communication Foundation (WCF) per generare un'eccezione se viene usato NTLM. L'impostazione di questa proprietà su false potrebbe non impedire l'invio di credenziali NTLM nella rete.

Nel codice seguente viene illustrato come disabilitare il fallback a NTLM.

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

Impossibile accedere a NTLM

Le credenziali client non sono valide per il servizio. Verificare che il nome utente e la password siano impostati correttamente e che corrispondano a un account noto al computer in cui viene eseguito il servizio. Per accedere al computer del servizio, NTLM utilizza le credenziali specificate. Anche se le credenziali possono essere valide nel computer in cui il client è in esecuzione, l'accesso non riuscirà se le credenziali non sono valide nel computer del servizio.

Si verifica un accesso NTLM anonimo, ma gli accessi anonimi sono disabilitati per impostazione predefinita

Quando si crea un client, la proprietà AllowedImpersonationLevel viene impostata su Anonymous, come illustrato nell'esempio seguente, ma per impostazione predefinita il server impedisce gli accessi anonimi. Tale situazione si verifica perché il valore predefinito della proprietà AllowAnonymousLogons della classe WindowsServiceCredential è false.

Nel codice client seguente viene tentata l'abilitazione degli accessi anonimi (si noti che la proprietà predefinita è 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

Nel codice del servizio seguente viene modificata l'impostazione predefinita per consentire gli accessi anonimi.

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

Per altre informazioni sulla rappresentazione, vedere Delega e rappresentazione.

In alternativa, il client viene eseguito come un servizio Windows, utilizzando l'account predefinito System.

Altri problemi

Le credenziali client non sono impostate correttamente

L'autenticazione di Windows utilizza l'istanza WindowsClientCredential restituita dalla proprietà ClientCredentials della classe ClientBase<TChannel>, non l'istanza UserNamePasswordClientCredential. Nel codice seguente viene illustrato un esempio non corretto.

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!

Nel codice seguente viene illustrato l'esempio corretto.

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()

L'interfaccia SSPI non è disponibile

I sistemi operativi seguenti non supportano l'autenticazione di Windows se usati come server: Windows XP Home Edition, Windows XP Media Center Edition e Windows XP Home Edition.

Sviluppo e distribuzione con identità diverse

Se l'applicazione viene sviluppata in un computer e distribuita in un altro e si utilizzano diversi tipi di account per l'autenticazione in ogni computer, potrebbe verificarsi un comportamento diverso. Si supponga, ad esempio, di sviluppare l'applicazione in un computer Windows XP Pro utilizzando la modalità di autenticazione SSPI Negotiated. Se si utilizza un account utente locale per l'autenticazione, verrà utilizzato il protocollo NTLM. Una volta sviluppata l'applicazione, il servizio viene distribuito in un computer Windows Server 2003 in cui è in esecuzione un account di dominio. A questo punto il client non è in grado di autenticare il servizio poiché usa Kerberos e un controller di dominio.

Vedi anche