2012-06-21 20 views
7

Perché il codice riportato di seguito funziona correttamente quando si esegue il localhost dell'applicazione Web ma non quando lo si installa su un server IIS?System.DirectoryServices.AccountManagement.UserPrincipal - localhost ma non iis

using (HostingEnvironment.Impersonate()) 
{ 
    UserPrincipal activeUser = UserPrincipal.Current; 
    String activeUserSid = activeUser.Sid.ToString(); 
    String activeUserUPN = activeUser.UserPrincipalName; 
} 

Si prega di non suggerire mi attengo con HttpContext.Current.User in quanto non fornisce l'accesso al SID o UPN senza ulteriori chiamate ad Active Directory.

L'applicazione Web verrà utilizzata dagli utenti autenticati di Windows da tre domini separati, il server Web è ospitato in un quarto dominio. Il pool di applicazioni è configurato per l'esecuzione con l'identità NetworkService e la configurazione dell'app Web ha la rappresentazione di identità impostata su true.

Il messaggio di errore quando viene eseguito su IIS è:

Error in Page_Load(): UserPrincipal.Current.
System.InvalidCastException: Unable to cast object of type 'System.DirectoryServices.AccountManagement.GroupPrincipal' to type 'System.DirectoryServices.AccountManagement.UserPrincipal'.
at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)
at System.DirectoryServices.AccountManagement.UserPrincipal.get_Current()
at webapp.Details.Default.Page_Load(Object sender, EventArgs e)

EDIT: provato sia il seguente e purtroppo ottenere lo stesso errore.

UserPrincipal userPrincipal = UserPrincipal.Current; 
Response.Write(userPrincipal.Name); 
Principal userOrGroup = UserPrincipal.Current; 
Response.Write(userOrGroup.Name); 

risposta

1

sembra bisogno di qualche altro metodo per determinare utente.
Qui la descrizione da msdn per la proprietà:
"Ottiene un oggetto principale utente che rappresenta l'utente corrente in cui è in esecuzione il thread."
Quindi UserPrincipal.Current restituisce l'utente in base a ciò che IIS è in esecuzione.

http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal.aspx

+0

Penso che tu abbia ragione. Questo non funziona ... var wi = HttpContext.Current.User.Identity as WindowsIdentity; utilizzando (wi.Impersonate()) { UserPrincipal up = UserPrincipal.Current; activeUserUPN = up.UserPrincipalName; activeUserSid = up.Sid.ToString(); } – RichardD

+1

"l'utente corrente in cui il thread è in esecuzione" in IIS è molto probabilmente l'identità del pool di app IIS; ma quando si esegue sul PC in Visual Studio, Casini o IIS Express, è in esecuzione come te. In tal caso, l'identità dell'utente viene condivisa dal client che richiede la pagina e dal server di sviluppo in esecuzione locale. –

3

ho avuto un sacco di problemi che implementano UserPrincipal.Current e ancora non comprendere appieno il motivo.

Alla fine ho finito con l'utilizzo di PrincipalSearcher e ho creato la seguente funzione per fare ciò che pensavo che UserPrincipal.Current stesse facendo.

private UserPrincipal GetActiveDirectoryUser(string userName) 
{ 
    using(var ctx = new PrincipalContext(ContextType.Domain)) 
    using(var user = new UserPrincipal(ctx) { SamAccountName = userName}) 
    using(var searcher = new PrincipalSearcher(user)) 
    { 
     return searcher.FindOne() as UserPrincipal; 
    } 
} 

E ho passato System.Web.HttpContext.Current.User.Identity.Name in quel metodo come nome utente.

+0

Viene visualizzato questo errore: 'System.ObjectDisposedException: impossibile accedere a un oggetto disposto. Nome oggetto: 'PrincipalContext'. su System.DirectoryServices.AccountManagement.PrincipalContext.CheckDisposed() su System.DirectoryServices.AccountManagement.PrincipalContext.get_ContextType() su System.DirectoryServices.AccountManagement.Principal.get_Name() su System.String.Concat (Object [] args) su Admin_Click (Oggetto mittente, EventArgs e) ' – SearchForKnowledge

+1

Ho provato più cose nella mia applicazione MVC. 'DirectoryEntry de = new DirectoryEntry (" WinNT: // "+ Ambiente.UserDomainName + "/" + userId); String username = de.Properties [ "FullName"] Value.ToString();. ' Poi ho provato' System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName; ' poi ha cercato la soluzione, ed è stata la solo uno da lavorare quando si distribuisce sul mio server di produzione ... non so perché. Tutto ha funzionato localmente ... –

Problemi correlati