6

Sto provando a far funzionare sia ActiveDirectory che i moduli standard, ma una cosa mi impedisce. Non riesco a ottenere il nome dell'utente Windows corrente. Il più vicino che ho è var i = WindowsIdentity.GetCurrent();, ma questo mi dà il nome dell'utente del pool di app IIS. Ho autenticazione anonima, autenticazione basata su form e autenticazione di Windows abilitata in IIS. Posso caricare utenti da AD quindi presumo che il mio web.config sia configurato correttamente.ActiveDirectory Nome utente corrente in ASP.NET

Edit: Questo è il mio web.config (usando un provider di facciata):

<membership defaultProvider="HybridMembershipProvider"> 
     <providers> 
     <clear /> 
     <add name="HybridMembershipProvider" type="MyApp.Data.HybridMembershipProvider" AspNetProviderName="AspNetSqlMembershipProvider" ActiveDirectoryProviderName="ADMembershipProvider" /> 
     <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MyAppConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> 
     <add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" 
      attributeMapUsername="sAMAccountName" enableSearchMethods="true" attributeMapEmail="mail"/> 
     </providers> 
    </membership> 

Edit 2: Ecco la mia configurazione di sicurezza di IIS.

IIS Security setup

risposta

4

Se si attiva la rappresentazione di ASP.Net in IIS, è possibile ottenere il nome utente come si desidera. Ciò funzionerà solo se tali dati sono nel provider di appartenenza moduli/AD , e loro non sono anonimi.

Inoltre, la miscelazione basata su form e l'autenticazione basata su Windows/AD è fattibile ma non consigliata. Vedi this se hai bisogno di farlo.

EDIT: Credo di aver capito male quello che volevi Quindi, ecco un alto livello sorvolare su ciò che accade con la soluzione di cui sopra:

se si spegne l'autenticazione anonima, e accendere Asp.Net rappresentazione , IIS eseguirà una sfida 401 ogni volta che qualcuno visiterà il sito.
Se tutto è nello stesso dominio, il browser Web invierà le credenziali a IIS, IIS le convaliderà con Active Directory, quindi AD fornirà a IIS un'identità con cui lavorare.

Quando si attiva la rappresentazione di Asp.Net, IIS associa l'identità al thread/richiesta corrente. Così, dopo l'autenticazione avviene, si può semplicemente prendere il nome utente dall'identità thread corrente, e quindi eseguire una query di Active Directory come:

using System.Threading; 
using System.DirectoryServices; 
using System.DirectoryServices.AccountManagement; 

...... 

PrincipalContext pc = null; 
UserPrincipal principal = null; 

try 
{ 
    var username = Thread.CurrentPrincipal.Identity.Name; 
    pc = new PrincipalContext(ContextType.Domain, "active.directory.domain.com"); 
    principal = UserPrincipal.FindByIdentity(pc, username); 

    var firstName = principal.GivenName ?? string.Empty 
    var lastName = principal.Surname ?? string.Empty 
    return string.Format("Hello {0} {1}!", firstName, lastName); 
} 
catch ... 
finally 
{ 
    if (principal != null) principal.Dispose(); 
    if (pc != null) pc.Dispose(); 
} 
+0

Potresti spiegare i tuoi primi due punti un po 'di più per favore? Cosa intendi "se questi dati sono nel provider di appartenenza/AD dei moduli". Sono un utente e posso interrogare AD per nome utente. "Altrimenti dovrai interrogare AD per ottenere il loro nome." -Posso farlo se ho il loro nome, ma come lo farei per ottenere il loro nome? – Echilon

+0

Risposta modificata per te, leggi ancora –

+0

Il problema che ho è che 'Thread.CurrentPrincipal.Identity.Name ' è vuoto, non riesco a ottenere il nome utente. – Echilon

-1

darei una prova con:

var i = Environment.CurrentUser;

e si può usare anche la mia classe: http://pastebin.com/xnYfVsLX

+0

non credo che la volontà lavoro per le app web, che presumo sia da quando ha citato i moduli auth – Eonasdan

1

Le applicazioni .Net che ho scritto dove mi Ho usato l'autenticazione di Windows Posso ancora usare User.Identity.Name per ottenere il nome utente di AD. Questo di solito include la DC, naturalmente, e restituisce il nome dell'account SAM dell'utente. Non stavo tentando di implementare entrambi contemporaneamente, ma per il User.Identity.Name funziona sicuramente

0

Questo è un segmento di codice che ho utilizzato nella mia app ASP.NET MVC non molto tempo fa, mi ha aiutato, non so se vi aiuterà, però, si è liberi di controllare se

private static void CheckIfUserExists(string p) 
    { 
     try 
     { 
       var user = (from x in Data.EntityDB.UserInfoes where x.SAMAccountName == p select x).FirstOrDefault(); 
       DirectoryEntry entry = new DirectoryEntry(Properties.Settings.Default.LDAPPath); //this is the connection to your active directory 
       DirectorySearcher search = new DirectorySearcher(entry); 
       search.PropertiesToLoad.Add("*"); 
       search.Filter = "(&(sAMAccountName=" + p + ")(objectCategory=person))"; 
       SearchResult searchResult = search.FindOne(); 
      //If the user under the alias is not found, Add a new user. Else, update his current data 
      if (user == null) 
      { 
       XXXXXXX.Models.UserInfo newUserEntry = new Models.UserInfo 
       { 
        SAMAccountName = p, 
        First_Name = searchResult.Properties.Contains("givenName") ? searchResult.Properties["givenName"][0].ToString() : string.Empty, 
        Last_Name = searchResult.Properties.Contains("sn") ? searchResult.Properties["sn"][0].ToString() : string.Empty, 
        Title = searchResult.Properties.Contains("title") ? searchResult.Properties["title"][0].ToString() : string.Empty, 
        Office = searchResult.Properties.Contains("l") ? searchResult.Properties["l"][0].ToString() : string.Empty, 
        Country = searchResult.Properties.Contains("c") ? searchResult.Properties["c"][0].ToString() : string.Empty, 
        Telephone = searchResult.Properties.Contains("telephoneNumber") ? searchResult.Properties["telephoneNumber"][0].ToString() : string.Empty, 
        Mobile_Phone = searchResult.Properties.Contains("mobile") ? searchResult.Properties["mobile"][0].ToString() : string.Empty, 
        Email_Address = searchResult.Properties.Contains("mail") ? searchResult.Properties["mail"][0].ToString() : string.Empty, 
        Image_Path = string.Format(Properties.Settings.Default.UserPicturePath, p), 
        LastUpdate = DateTime.Now, 
       }; 

aggiornamento

preavviso Prendere che ho anche interrogato un database diverso in questo estratto, ignorare tutte le dichiarazioni Linq. Le classi DirectoryEntry, DirectorySearcher e SearchResult devono aiutarti con ciò di cui hai bisogno.

aggiornamento 2 la variabile p può essere sostituito dal HttpContext.Current.User.Identity proprietà

aggiornamento 3 Ecco un elenco aggiornato dei nomi LDAP (dove si vede searchResult.Properties.Contains ("") Over here che punta a diversi attributi utente nella directory attiva

+0

Il problema è che 'HttpContext.Cu rrent.User.Identity' è vuoto e IsAuthenticated è falso, quindi non ho username, anche se sono su un account AD. – Echilon

+0

Questo è strano. hai impostato il tag nel tuo web.config sulla tua connessione LDAP? perché, se sì, e puoi accedere, HttpContext.Current.User.L'identità non deve essere nullo – Eon

+0

Eon

1

Prova questo se si utilizza l'autenticazione forme con Active Directory:

Context.User.Identity.Name 

// frammento di codice

sub Page_Load(sender as object, e as EventArgs) 
    lblName.Text = "Hello " + Context.User.Identity.Name & "." 
    lblAuthType.Text = "You were authenticated using " & Context.User.Identity.AuthenticationType & "." 
end sub 

Rif:
Active Directory Authentication from ASP .NET
How to authenticate against the Active Directory by using forms authentication and Visual Basic .NET Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication

Rif: È possibile utilizzare l'autenticazione di Windows con ASP.NET in diversi modi:

  • l'autenticazione di Windows senza la rappresentazione. Questa è l'impostazione predefinita. ASP.NET esegue operazioni e accede alle risorse utilizzando l'identità del processo dell'applicazione, che per impostazione predefinita è l'account Servizio di rete su Windows Server 2003.

  • Autenticazione di Windows con impersonificazione. Con questo approccio, impersonare l'utente autenticato e utilizzare tale identità per eseguire operazioni e accedere alle risorse.

  • Autenticazione di Windows con rappresentazione di identità fissa. Con questo approccio, impersoni un account fisso di Windows per accedere alle risorse utilizzando un'identità specifica. Su Windows Server 2003, è necessario evitare questo approccio di rappresentazione; al contrario, utilizzare un pool di applicazioni personalizzato con un'identità di servizio personalizzata.

Come da documentazione è possibile ottenere il token Windows dell'utente autenticato.

IIdentity WinId= HttpContext.Current.User.Identity; 
WindowsIdentity wi = (WindowsIdentity)WinId; 

Se c'è qualcosa che non va quindi controllare l'applicazione rappresentazione metodo come per la documentazione MSDN di How To: Use Windows Authentication in ASP.NET 2.0

fare riferimento l'articolo di ScottGu Recipe: Enabling Windows Authentication within an Intranet ASP.NET Web application

+0

NB: non si applica quando Autenticazione moduli in uso. Ho usato questo con ASP.NET MVC e System.Web.HttpContext.Current.User sarà un oggetto System.Web.Security.FormsIdentity. –