2010-10-26 4 views
18

Come posso implementare segue in un'applicazione ASP.NET MVC:Come supportare l'autenticazione NTLM con fallback per form in ASP.NET MVC?

  1. utente apre il sito intranet
  2. utente viene autenticato in silenzio, se possibile
  3. se l'autenticazione NTLM non ha funzionato, modulo spettacolo di login per l'utente
  4. utente indicare la password di accesso e selezionare dominio dalla lista di domini predefiniti
  5. utente viene autenticato nel codice utilizza AD

So come implementare 4 e 5 ma non riesco a trovare informazioni su come combinare NTLM e moduli. In modo che la finestra di dialogo nativa/password nativa di NTLM non venga mai visualizzata: autenticazione trasparente o pagina di login dall'aspetto piacevole.

Come dovrebbe funzionare? Dovrebbe essere chiesto all'utente login e password? Le sue attuali credenziali (nome utente dominio) possono essere utilizzate senza chiedere di inserire login e password?

di aggiornamento per questi, indagare stesso problema:

Quando mi è stato chiesto questo non mi è stato completamente capire come l'autenticazione NTLM funziona internamente. La cosa importante da capire è che se il browser dell'utente non supporta correttamente NTLM o se il supporto NTLM è disabilitato dall'utente, il server non avrà mai la possibilità di aggirare questo problema.

Come autenticazione di Windows sta lavorando:

  1. cliente trasmette una richiesta HTTP regolare al server
  2. Server risponde con stato HTTP 401 e l'indicazione che l'autenticazione NTLM deve essere utilizzato per accedere alle risorse
  3. client inviare NTLM Messaggio Type1
  4. Il server risponde con il messaggio NTLM Tipo2 con la richiesta di verifica
  5. Il client invia un messaggio tipo3 con risposta alla richiesta
  6. Server risponde con il contenuto effettivo richiesto

Come si vede, il browser che non supportano NTLM non andrà al punto di errore (3), IIS invece verrà mostrato all'utente generati 401 pagina.

Se l'utente non dispone di credenziali, dopo aver annullato il browser di finestra di dialogo di autenticazione NTLM non continuerà anche a (3).

Quindi non abbiamo la possibilità di reindirizzare automaticamente gli utenti alla pagina di accesso personalizzata.

L'unica opzione qui è avere una pagina "gateway" in cui decidiamo se l'utente deve supportare NTLM e, in caso affermativo, reindirizzare alla home page protetta NTLM.

E in caso contrario, mostrare il modulo di accesso e consentire l'autenticazione inserendo manualmente login e password.

La decisione viene generalmente effettuata in base all'indirizzo IP e/o al nome host degli utenti tramite l'assegnazione di intervalli IP o la verifica della tabella degli IP predefiniti.

+0

http: // StackOverflow. it/questions/492977/anonymous-access-and-ntlm-authentication-in-iis –

risposta

8

Questo articolo potrebbe farti puntare nella giusta direzione. Fondamentalmente hai due app in due directory virtuali con lo stesso nome host. Un'app utilizza l'autenticazione basata su form, una utilizza Windows. Quello che utilizza l'autenticazione di Windows crea un cookie di autenticazione del modulo valido e reindirizza alla seconda directory virtuale.

ASP.NET Mixed Mode Authentication

0

Non si può avere sia NTLM e FormsAuthentication nella stessa applicazione ASP.NET. Avrai bisogno di due diverse applicazioni in directory virtuali separate.

+6

Non completamente vero - non è possibile configurare (tramite web.config) un'applicazione per supportare l'autenticazione NTLM e Forms, ma non c'è motivo per cui non si possa 'creare un modulo di autenticazione personalizzato per gestirlo. – Keith

2

Ho questa impostazione esatta in produzione, ho configurato il mio portale per utilizzare FormsAuth e ho scritto una funzione che richiede ai visitatori l'IP di cercare l'account utente che ha effettuato l'accesso a tale IP/PC. Utilizzando il nome che trovo (ad esempio DOMAIN\user), ho verificato che il dominio corrisponda al mio dominio e che il nome utente/account sia valido nel mio provider FormsAth utilizzando Membership.GetUser(<user>). Se questa chiamata restituisce una corrispondenza e l'utente IsApproved creo un cookie & & per l'utente. Ho più di 400 persone sulla rete e questo funziona perfettamente, gli unici computer che ancora effettuano il login sono (1. Utenti senza account nel mio portale, 2. Alcuni utenti MAC/Linux, 3. Utenti mobili che non sono stati avviati sulla rete e avevano i Criteri di gruppo che abilitano il loro Firewall in alto).

La cattura di questa soluzione è che non richiede rappresentazione di un account di dominio amministratore per interrogare il PC degli utenti, e che si utilizza il codice non gestito netapi32.dll.

Ecco il codice che uso (chiamate di funzione esterna non fornite, per brevità). Ho provato a semplificare un po 'questo, poiché ho MOLTE chiamate esterne.

string account = String.Empty; 
string domain = String.Empty; 
string user = String.Empty; 


ImpersonateUser iu = new ImpersonateUser(); //Helper that Enabled Impersonation 
if (iu.impersonateValidUser(StringHelper.GetAppSetting("DomainAccount"), StringHelper.GetAppSetting("DomainName"), StringHelper.GetEncryptedAppSetting("DomainAccountPassword"))) 
{ 
    NetWorkstationUserEnum nws = new NetWorkstationUserEnum(); //Wrapper for netapi32.dll (Tested on Vista, XP, Win2K, Win2K3, Win2K8) 
    string host = nws.DNSLookup(Request.UserHostAddress); // netapi32.dll requires a host name, not an IP address 

    string[] users = nws.ScanHost(host); // Gets the users/accounts logged in 

    if (nws.ScanHost(host).Length > 0) 
    { 
     string workstationaccount = string.Empty; 

     if (host.IndexOf('.') == -1) // Pick which account to use, I have 99.9% success with this logic (only time doesn't work is when you run a interactive process as a admin e.g. Run As <process>). 
     { 
      workstationaccount = String.Format("{0}\\{1}$",StringHelper.GetAppSetting("DomainName"), host).ToUpper(); 
     } 
     else 
     { 
      workstationaccount = String.Format("{0}\\{1}$", StringHelper.GetAppSetting("DomainName"), host.Substring(0, host.IndexOf('.'))).ToUpperInvariant(); 
     } 

     account = users[users.Length - 1].Equals(workstationaccount) ? users[0] : users[users.Length - 1]; 

     domain = account.Substring(0, account.IndexOf("\\")); 
     user = account.Substring(account.IndexOf("\\") + 1, 
           account.Length - account.IndexOf("\\") - 1); 
    } 

    iu.undoImpersonation(); // Disable Impersonation 
} 

Ora utilizzando l'account abbiamo preso nella prima funzione/processo, ora cerchiamo di verificare e decidere se si debba mostrare un login o auto-login l'utente.

MembershipUser membershipUser = Membership.GetUser(user); 

if (membershipUser != null && membershipUser.IsApproved) 
{ 
    string userRoles = string.Empty; // Get all their roles 
    FormsAuthenticationUtil.RedirectFromLoginPage(user, userRoles, true); // Create FormsAuthTicket + Cookie + 
} 

ho scritto un post su questo blog molto tempo fa, ecco un link per il wrapper per netapi32.dll e la mia rappresentazione di supporto che ho fornito nel post Source Code Download

+1

grazie per la tua risposta dettagliata, non sto contrassegnando come risposta ancora come penso che possa avere preoccupazioni per la sicurezza e nel complesso ha una sensazione di 'hacking' :-) –

+1

E 'sicuramente un hack .. – Zachary