2009-06-22 6 views
6

Ho eseguito la rappresentazione in SharePoint piuttosto un po 'in passato facendo qualcosa come la seguente.È possibile eseguire una ricerca rappresentata in SharePoint senza fornire una password?

SPWeb web = SPContext.Current.Web; 
string currentWebUrl = web.Url; 
SPUser user = web.EnsureUser(loginToImpersonate); 
using (SPSite site = new SPSite(currentWebUrl, user.UserToken) 
{ 
    using (SPWeb impersonatedWeb = site.OpenWeb()) 
    { 
     // Any SharePoint access here to 'impersonatedWeb' 
     // is impersonated as 'loginToImpersonate' 
    } 
} 

Si noti che questo non richiede la password dell'utente che si sta impersonando, ma richiede certa protezione dall'accesso di codice per l'esecuzione. Come nota a margine, la chiamata di ConfirmUser richiede anche che l'utente corrente sia un amministratore, ma esistono altri metodi che possono essere utilizzati al posto di CleanUser per ottenere l'oggetto SPUser (cercando di mantenere il mio frammento di codice semplice per questa domanda).

Ora che ho impostato il livello ... Ora desidero fare una FullTextSQLQuery o una KeywordQuery con il motore di query MOSS o WSS e ottenere risultati di sicurezza troncati in base a un utente rappresentato. Entrambi gli oggetti possono assumere un SPSite sul costruttore, ma ignorano la mia logica di rappresentazione. Vanno invece con l'utente attualmente connesso (HTTPContext.Current.User).

Ci sono anche altri costruttori: nome dell'applicazione (stringa) e per MOSS ce n'è uno con un ServerContext per il provider di servizi condivisi, ma non credo che ciò possa essere di aiuto.

Ho usato Reflector sulla classe KeywordQuery e la sua classe Query di base e diventa piuttosto brutto piuttosto veloce. Credo che la logica effettiva che determina l'utente sia in codice non gestito.

Quindi, è possibile per me farlo?

+0

Link di lavoro: http://www.threewill.com/2010/06/connect-to-sharepoint-forwarding-user-identities/ – KjellSj

risposta

1

si scopre che si ca n esegue la ricerca rappresentata in SharePoint senza password. Lo abbiamo capito nell'agosto del 2009 e sono stato negligente nell'aggiornare Stack Overflow con la risposta.

Vedere http://wiki.threewill.com/display/is/2010/06/18/Connect+to+SharePoint+-+Forwarding+User+Identities per i dettagli e prestare particolare attenzione ai requisiti speciali. Nota che funziona con SharePoint 2007 e SharePoint 2010.

Mille grazie al mio collega Eric Bowden che ha fatto tutto il lavoro!

+2

Appare il link è rotto? –

+0

Link di lavoro: http://www.threewill.com/2010/06/connect-to-sharepoint-forwarding-user-identities/ –

+0

Grazie per aver trovato il collegamento aggiornato. Non sapevo dove fosse me stesso! –

4

Per eseguire questa operazione è necessaria una vera e propria rappresentazione di Windows. La rappresentazione di SPSite non è una vera e propria rappresentazione - dice semplicemente al modello di oggetto WSS di scrivere un altro ID utente per i campi creati e modificati nel database del contenuto.

Per Windows rappresentazione avrete purtroppo bisogno sia l'accesso e la password se non si desidera rappresentare l'account del pool di applicazioni utilizzando SPSecurity.RunWithElevatedPrivileges

È possibile implementare la rappresentazione di Windows come segue:

using (Impersonator imp = new Impersonator("user", "domain", "password")) 
{ 
    // Do stuff impersonated 
} 

in cui la classe Impersonator è implementato come:

public sealed class Impersonator : IDisposable 
{ 
    private WindowsImpersonationContext impersonationContext; 

    public Impersonator(string user, string domain, string password) 
    { 
    WindowsIdentity id = Logon(user, domain, password); 
    impersonationContext = id.Impersonate(); 
    } 

    public void Dispose() 
    { 
    if (impersonationContext != null) 
    { 
     impersonationContext.Undo(); 
     impersonationContext = null; 
    } 
    } 

    private WindowsIdentity Logon(string user, string domain, string password) 
    { 
    WindowsIdentity identity; 
    IntPtr handle = IntPtr.Zero; 
    bool logonSucceeded = LogonUser(
     user, domain, password, 
     8, // LOGON32_LOGON_NETWORK_CLEARTEXT 
     0, // LOGON32_PROVIDER_DEFAULT 
     ref handle); 

    if (!logonSucceeded) 
    { 
     int errorCode = Marshal.GetLastWin32Error(); 
     throw new UnauthorizedAccessException("User logon failed. Error Number: " + errorCode); 
    } 

    identity = new WindowsIdentity(handle); 
    CloseHandle(handle); 

    return identity; 
    } 

    [DllImport("advapi32.dll", SetLastError = true)] 
    private static extern bool LogonUser(string lpszUsername, 
    string lpszDomain, 
    string lpszPassword, 
    int dwLogonType, 
    int dwLogonProvider, 
    ref IntPtr phToken); 

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

Grazie, Lars. Non è la risposta che volevo sentire, ovviamente, ma è bello sapere quali sono le mie opzioni. Apprezzo la classe Impersonator. Sembra carino –

+0

Buone cose Lars, grazie per questo. –

0

In realtà esiste un altro modo di eseguire la rappresentazione quando si eseguono ricerche utilizzando il modello di oggetti. Sono stato in grado di farlo funzionare facendo la rappresentazione durante l'esecuzione con privilegi elevati. vedere il mio post qui: http://vishalseth.com/post/2013/11/05/Impersonated-Searching-against-SharePoint.aspx

+1

Sebbene questo collegamento possa rispondere alla domanda, è necessario riepilogare o citare l'articolo perché i collegamenti tendono a decadere nel tempo. – pinckerman