Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Quando si usa l'autenticazione di Windows come meccanismo di sicurezza, l'interfaccia SSPI (Security Support Provider Interface) gestisce i processi di sicurezza. Quando si verificano errori di sicurezza a livello SSPI, vengono visualizzati da Windows Communication Foundation (WCF). Questo argomento fornisce un framework e un set di domande che consentono di diagnosticare gli errori.
Per una panoramica del protocollo Kerberos, vedere Kerberos Explained; per una panoramica di SSPI, vedere SSPI.
Per l'autenticazione di Windows, WCF utilizza solitamente il provider di supporto per la sicurezza Negotiate (SSP), 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 a NT LAN Manager (NTLM). Tuttavia, è possibile configurare WCF in modo che usi solo il protocollo Kerberos e per generare un'eccezione se Kerberos non è disponibile. È anche possibile configurare WCF per l'uso di forme limitate del protocollo Kerberos.
Metodologia di debug
Il metodo di base è il seguente:
Determinare se si usa l'autenticazione di Windows. Se si usa qualsiasi altro schema, questo argomento non si applica.
Se si è certi di usare l'autenticazione di Windows, determinare se la configurazione WCF usa Kerberos direct o Negotiate.
Dopo aver determinato se la configurazione usa il protocollo Kerberos o NTLM, è possibile comprendere i messaggi di errore nel contesto corretto.
Disponibilità del protocollo Kerberos e NTLM
Il provider di servizi condivisi Kerberos richiede che un controller di dominio funga da Centro distribuzione chiavi Kerberos (KDC). Il protocollo Kerberos è disponibile solo quando il client e il servizio usano identità di dominio. In altre combinazioni di account viene usato NTLM, come riepilogato nella tabella seguente.
Le intestazioni di tabella mostrano i possibili tipi di account utilizzati dal server. La colonna a sinistra mostra i possibili tipi di account usati dal client.
| Utente locale | Sistema locale | Utente di dominio | Computer di 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 di dominio | NTLM | NTLM | Kerberos | Kerberos |
In particolare, i quattro tipi di account includono:
Utente locale: profilo utente esclusivo per macchina. Ad esempio:
MachineName\AdministratoroMachineName\ProfileName.Sistema locale: l'account predefinito SYSTEM su un computer che non è collegato a un dominio.
Utente di dominio: un account utente in un dominio di Windows. Ad esempio:
DomainName\ProfileName.Computer di dominio: un processo con identità macchina in esecuzione su una macchina connessa a un dominio Windows. Ad esempio:
MachineName\Network Service.
Annotazioni
Le credenziali del servizio vengono acquisite quando viene chiamato il Open metodo della ServiceHost classe . Le credenziali client vengono lette ogni volta che il client invia un messaggio.
Problemi comuni di autenticazione di Windows
Questa sezione illustra alcuni problemi comuni di autenticazione di Windows e possibili rimedi.
Protocollo Kerberos
Problemi di SPN/UPN con il protocollo Kerberos
Quando si usa l'autenticazione di Windows e il protocollo Kerberos viene usato o negoziato da SSPI, l'URL usato dall'endpoint client deve includere il nome di dominio completo dell'host del servizio all'interno dell'URL del servizio. Ciò presuppone che l'account sotto il quale il servizio è in esecuzione abbia accesso alla chiave del nome dell'entità servizio (SPN) del computer (impostazione predefinita) creata quando il computer viene aggiunto all'Active Directory, operazione eseguita più comunemente eseguendo il servizio nell'account Servizio di rete. Se il servizio non ha accesso alla chiave SPN del computer, è necessario specificare il nome SPN o l'entità utente (UPN) corretto dell'account con cui il servizio è in esecuzione nell'identità dell'endpoint del client. Per altre informazioni sul funzionamento di WCF con SPN e UPN, vedere Identità e autenticazione del servizio.
Negli scenari di bilanciamento del carico, ad esempio web farm o giardini Web, una procedura comune consiste nel definire un account univoco per ogni applicazione, assegnare un nome SPN a tale account e assicurarsi che tutti i servizi dell'applicazione vengano eseguiti in tale account.
Per ottenere un nome SPN per l'account del servizio, è necessario essere un amministratore di dominio di Active Directory. Per altre informazioni, vedere Supplemento tecnico Kerberos per Windows.
Il protocollo Kerberos Direct richiede che il servizio venga eseguito con un account macchina di dominio
Ciò si verifica quando la ClientCredentialType proprietà è impostata su Windows e la NegotiateServiceCredential proprietà è 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 il problemi, eseguire il servizio usando un account del computer di dominio, ad esempio servizio di rete, in un computer aggiunto a un dominio.
La delega richiede la negoziazione delle credenziali
Per usare il protocollo di autenticazione Kerberos con la delega, è necessario implementare il protocollo Kerberos con la negoziazione delle credenziali (talvolta denominata "multi-leg" o "multi-step" Kerberos). Se si implementa l'autenticazione Kerberos senza negoziazione delle credenziali (talvolta denominata "one-shot" o "single-leg" Kerberos), verrà generata un'eccezione.
Per implementare Kerberos con negoziazione delle credenziali, seguire questa procedura:
Implementare la delega impostando AllowedImpersonationLevel su Delegation.
Richiedi negoziazione SSPI:
Se si usano associazioni standard, impostare la
NegotiateServiceCredentialproprietà sutrue.Se si usano associazioni personalizzate, impostare l'attributo
AuthenticationModedell'elementoSecuritysuSspiNegotiated.
Richiedere alla negoziazione SSPI di utilizzare Kerberos escludendo l'uso di NTLM.
Eseguire questa operazione nel codice con l'istruzione seguente:
ChannelFactory.Credentials.Windows.AllowNtlm = falseIn alternativa, è possibile eseguire questa operazione nel file di configurazione impostando l'attributo
allowNtlmsufalse. Questo attributo è contenuto nelle <finestre>.
Protocollo NTLM
Negotiate SSP passa a NTLM, ma NTLM è disabilitato
La AllowNtlm proprietà è impostata su false, il che induce Windows Communication Foundation (WCF) a tentare di generare un'eccezione se viene utilizzato NTLM. L'impostazione di questa proprietà su false potrebbe non impedire l'invio delle credenziali NTLM attraverso la rete.
Di seguito 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
Errore di accesso NTLM
Le credenziali client non sono valide nel servizio. Verificare che il nome utente e la password siano impostati correttamente e corrispondano a un account noto al computer in cui è in esecuzione il servizio. NTLM usa le credenziali specificate per accedere al computer del servizio. Anche se le credenziali potrebbero essere valide nel computer in cui è in esecuzione il client, l'accesso avrà esito negativo se le credenziali non sono valide nel computer del servizio.
Si verifica l'accesso NTLM anonimo, ma gli accessi anonimi sono disabilitati per impostazione predefinita
Quando si crea un client, la AllowedImpersonationLevel proprietà è impostata su Anonymous, come illustrato nell'esempio seguente, ma per impostazione predefinita il server non consente accessi anonimi. Ciò si verifica perché il valore predefinito della AllowAnonymousLogons proprietà della WindowsServiceCredential classe è false.
Il codice client seguente tenta di abilitare gli 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
Il codice del servizio seguente modifica l'impostazione predefinita per abilitare gli accessi anonimi dal server.
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 ulteriori informazioni sull'impersonazione, vedere Delega e Impersonazione.
In alternativa, il client è in esecuzione come servizio Windows, usando l'account predefinito SYSTEM.
Altri problemi
Le credenziali client non sono impostate correttamente
L'autenticazione di Windows usa l'istanza WindowsClientCredential restituita dalla ClientCredentials proprietà della ClientBase<TChannel> classe , non dall'oggetto UserNamePasswordClientCredential. Di seguito è riportato un esempio errato.
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!
Di seguito 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()
SSPI non è disponibile
I sistemi operativi seguenti non supportano l'autenticazione di Windows quando vengono usati come server: Windows XP Home Edition, Windows XP Media Center Edition e Windows Vista Home Edition.
Sviluppo e distribuzione con identità diverse
Se si sviluppa l'applicazione in un computer e si distribuisce in un altro e si usano tipi di account diversi per l'autenticazione in ogni computer, è possibile che si verifichi un comportamento diverso. Si supponga, ad esempio, di sviluppare l'applicazione in un computer Windows XP Pro usando la SSPI Negotiated modalità di autenticazione. Se si usa un account utente locale per l'autenticazione, verrà usato il protocollo NTLM. Una volta sviluppata l'applicazione, si distribuisce il servizio in un computer Windows Server 2003 in cui viene eseguito con un account di dominio. A questo punto, il client non sarà in grado di autenticare il servizio perché usa Kerberos e un controller di dominio.