11

Ecco quello che ho cercato di farePosso impersonare un client autenticato con l'autenticazione di moduli e stabilire una connessione affidabile a SQL Server?

creare un'applicazione ASP.NET MVC 3 con autenticazione basata su form e l'appartenenza di Active Directory. Il server web e il database sono server fisici diversi, quindi un doppio salto.

Pensavo che la risposta fosse questo vecchio articolo su constrained delegation and protocol transition? Finora, non sono stato in grado di far funzionare la tecnica.

Lo sto testando dal mio computer DEV (Windows 7, IIS7) per il server Web prima della distribuzione in Windows 2008 (IIS7) nell'impostazione di produzione. Windows 2008 farebbe la differenza?

Cosa funziona e cosa fallisce

sono in grado di effettuare il login con le forme auth e l'appartenenza AD. Questo sembra funzionare bene. Quando provo a fare una chiamata di database utilizzando questo codice:

public void AsUser(Action action) 
    { 
     using (var id = new WindowsIdentity(User.Identity.Name + @"@example.com")) 
     { 
      WindowsImpersonationContext context = null; 
      try 
      { 
       context = id.Impersonate(); 
       action.Invoke(); 
      } 
      catch (Exception ex) 
      { 
       // ex.Message is The type initializer for System.Data.SqlClient.SqlConnection threw an exception 
       // buried inner exeption is Requested registry access is not allowed 
      } 
      finally 
      { 
       if (context != null) 
       { 
        context.Undo(); 
       } 
      } 
     } 
    } 

Non riesce con un'eccezione mi porta a credere che ho problemi di installazione sul mio server DEV locale. L'eccezione interna è Requested registry access is not allowed.

Se ho impostato un punto di interruzione e ispezionare la WindowsIdentity dopo la chiamata Impersonate() vedo che il ImpersonationLevel è impostato su Identification. Sembra un indizio che non sia configurato correttamente. Qualcuno può confermare?

Sono sulla buona strada ed è possibile anche impostarlo? Qualsiasi suggerimento sarebbe apprezzato.

risposta

5

Penso che tu sia sulla strada giusta. Hai solo bisogno di più interventi di risoluzione dei problemi sulla configurazione della transizione del protocollo.

Presumo che sia stato configurato correttamente il provider di appartenenze di Active Directory in modo che sia possibile accedere correttamente alla pagina Web utilizzando il nome utente e la password della directory attiva. Se non è così, per favore ignora il resto della mia risposta :)

Da quello che ho visto nella tua domanda, hai ottenuto il token dell'utente usando S4USelf da WindowsIdentity. Quindi, si sta utilizzando S4UProxy per passare il token rappresentato al server SQL. Dal momento che hai detto che hai solo ImpersonationLevel.Identification, significa che non hai eseguito la transizione del protocollo.

È necessario comprendere che consentire a una macchina di eseguire la transizione del protocollo in un dominio è un privilegio molto elevato.Concedere un server per eseguire la transizione del protocollo significa quasi che il server è quasi come un controller di dominio. È necessario prendere consapevolmente questa decisione in AD per trasformare un server in questa capacità e devi essere un amministratore di domian per apportare questa modifica. Se non lo hai fatto, probabilmente non hai impostato correttamente le tue cose.

Ci sono un paio di cose da controllare.

Prima di tutto, assicurati di aver selezionato "Considera attendibile questo computer per la delega solo ai servizi specificati" e quindi hai selezionato "seleziona Utilizza qualsiasi protocollo di autenticazione" nel tuo account di servizio. Ti potrebbe piacere creare un account di dominio. Here è un collegamento su come creare un account di servizio per ASP.NET. Ricorda, hai bisogno di un account di dominio. Dopo aver creato un account di servizio di dominio, assicurati di andare alla scheda delega su quell'account e selezionare le opzioni corrette.

In secondo luogo, è necessario assicurarsi che gli SPN siano impostati correttamente. Mi rendo conto che il link che hai postato menziona solo l'SPN del tuo account di servizio ASP.NET. In realtà, devi anche assicurarti che l'account di servizio sul tuo server SQL sia impostato correttamente. Altrimenti, Windows non utilizzerà affatto l'autenticazione Kerberos. Ricadrà per utilizzare NTLM. Ci sono molti dettagli per configurare correttamente un SPN sul server SQL. Puoi controllare prima here e vedere se hai fortuna. Dalla mia esperienza, la maggior parte degli amministratori di database non sa come configurarli correttamente. Non lo sanno nemmeno perché la maggior parte delle applicazioni funziona bene con NTLM. È necessario prestare attenzione all'account del servizio SQL Server e al numero di porta che sta utilizzando.

In terzo luogo, è necessario assicurarsi che non vi sia nulla che disabiliti la propria delega Kerberos. Alcuni account AD sensibili non sono delegati per impostazione predefinita. Ad esempio, l'account amministratore integrato. Quindi, è meglio utilizzare alcuni altri account utente normali a scopo di test.

UPDATE

Ho appena trovato another article vi insegna come impostare la transizione protocollo per ASP.NET. Ha affermato che è necessario concedere il diritto TCB all'account del servizio IIS per assicurarsi che possa creare un tipo di WindowsIdentity Impersonation. Puoi dare un colpo.

+0

Grazie per tutte le informazioni. Molte cose erano nuove per me. Non ho ancora avuto il tempo di resettare tutto e iniziare con questa nuova conoscenza, ma sono più fiducioso di poterlo far funzionare ora. –

+0

Questo tipo fa schifo ... con 13 minuti fino a quando la taglia è scaduta, ho scelto la tua come risposta, non rendendomi conto che è diverso da "assegnare" la taglia. Hai metà di quello che dovresti avere. Mi dispiace di non aver capito il sistema o forse ho perso gli indizi nell'interfaccia utente - in entrambi i casi il mio male. –

+0

@Aaron Nessuna preoccupazione. Grazie per aver accettato la mia risposta. Dopo aver ottenuto il funzionamento del protocollo transistor, ci sono in realtà alcuni problemi di kerberos più generali che potresti incontrare. Per esempio. se ci sono SPN duplicati nella stessa foresta AD, l'autenticazione Kerberos smetterà di funzionare in silenzio. È molto difficile scrivere una risposta completa a questo tipo di domande. Se possibile, MSDN non avrà bisogno di avere più articoli e KB per problemi simili. Se ti imbatti in altri problemi di AD, tagga una domanda con 'active-directory'. Potresti ricevere suggerimenti più utili –

1

È inoltre necessario verificare con l'amministrazione di AD per verificare se è consentita la rappresentazione. Le politiche AD delle mie aziende non consentiranno la rappresentazione.

2

Qui la classe che uso. Inoltre, ti consigliamo di controllare e vedere se il processo in cui è in esecuzione l'AppPool ha abbastanza autorizzazioni per eseguire la rappresentazione poiché è un'attività privilegiata. Darei all'account utente che il pool di app è in esecuzione con privilegi di amministratore temporanei (ovviamente solo la finestra di sviluppo) e vedere se funziona in modo da sapere se si tratta di un problema di autorizzazioni.

public class ImpersonationHelper : IDisposable 
    { 
     private const int LOGON32_LOGON_INTERACTIVE = 2; 
     private const int LOGON32_PROVIDER_DEFAULT = 0; 
     private WindowsImpersonationContext _impersonationContext; 
     private string _userName; 
     private string _domain; 
     private string _password; 

     [DllImport("advapi32.dll")] 
     public static extern int LogonUserA(String lpszUserName, 
      String lpszDomain, 
      String lpszPassword, 
      int dwLogonType, 
      int dwLogonProvider, 
      ref IntPtr phToken); 
     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern int DuplicateToken(IntPtr hToken, 
      int impersonationLevel, 
      ref IntPtr hNewToken); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern bool RevertToSelf(); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
     public static extern bool CloseHandle(IntPtr handle); 

     public ImpersonationHelper(string domain, string userName, string password) 
     { 
      _userName = userName; 
      _domain = domain; 
      _password = password; 
     } 

     public void Start() 
     { 
      WindowsIdentity tempWindowsIdentity; 
      IntPtr token = IntPtr.Zero; 
      IntPtr tokenDuplicate = IntPtr.Zero; 

      if (RevertToSelf()) 
      { 
       if (LogonUserA(_userName, _domain, _password, LOGON32_LOGON_INTERACTIVE, 
        LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
       { 
        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
        { 
         tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); 
         _impersonationContext = tempWindowsIdentity.Impersonate(); 
         if (_impersonationContext != null) 
         { 
          CloseHandle(token); 
          CloseHandle(tokenDuplicate); 
         } 
        } 
       } 
      } 
      if (token != IntPtr.Zero) 
       CloseHandle(token); 
      if (tokenDuplicate != IntPtr.Zero) 
       CloseHandle(tokenDuplicate); 
     } 

     #region IDisposable Members 

     void IDisposable.Dispose() 
     { 
      if (_impersonationContext != null) 
      { 
       _impersonationContext.Undo(); 
      } 
     } 

     #endregion 
    } 
+0

Grazie per il codice. Spero di rimanere in una terra felice gestita senza le chiamate esterne, ma se si tratta di questo, darò una possibilità. –

1

Penso che tu abbia identificato il problema ma nessuno lo ha menzionato. Il problema del "doppio salto" non ti consentirà di farlo. Non è possibile. Ci sono molte persone che hanno scritto a riguardo come Scott Forsyth.

Quando l'autenticazione al server IIS utilizzando l'autenticazione integrata , che utilizza il vostro prima 'hop'. Quando IIS tenta di accedere a un dispositivo di rete, quello sarebbe il doppio o secondo salto che non è consentito. IIS non può a sua volta passare le credenziali alla rete successiva , altrimenti lo sviluppatore o l'amministratore potrebbe abusare delle credenziali e utilizzarle in modi che il visitatore del sito non ha previsto in visitatore.

Questo non si verifica con accesso anonimo o con la rappresentazione fuori perché in tal caso IIS si prende cura di voi autenticazione e poi si utilizza un utente diverso per l'accesso locale o di rete . Ciò significa che il pool di app identità o utente anonimo può effettuare una chiamata di rete come primo salto.

Penso che sia abbastanza chiaro che non è possibile passare le credenziali oltre la prima connessione.

Problemi correlati