Domanda

Ho fatto la rappresentazione in SharePoint un bel po 'in passato facendo qualcosa come il seguente.

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'
    }
}

Nota che questo non richiede la password dell'utente che stai impersonando, ma richiede una certa sicurezza di accesso al codice per l'esecuzione. Come nota a margine, anche la chiamata di TrustedUser richiede che l'utente corrente sia un amministratore, ma ci sono altri metodi che possono essere usati al posto di GuaranteUser per ottenere l'oggetto SPUser (cercando di mantenere semplice il mio frammento di codice per questa domanda).

Ora che ho impostato il palcoscenico ... Ora voglio fare un FullTextSQLQuery o un KeywordQuery contro il motore di query MOSS o WSS e ottenere risultati con limiti di sicurezza basati su un utente impersonato. Entrambi gli oggetti possono prendere un SPSite nel costruttore, ma ignorare la mia logica di rappresentazione. Vanno invece con l'utente attualmente connesso (HTTPContext.Current.User).

Esistono anche altri costruttori: nome dell'applicazione (stringa) e per MOSS ce n'è uno con un ServerContext al provider di servizi condivisi, ma non credo che questi aiuteranno affatto.

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

Quindi, è possibile per me farlo?

È stato utile?

Soluzione 2

Si scopre che puoi eseguire ricerche impersonate in SharePoint senza password. L'abbiamo capito nell'agosto del 2009 e sono stato negligente nell'aggiornamento Stack Overflow con la risposta.

Vedi 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 sia con SharePoint 2007 che SharePoint 2010.

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

Altri suggerimenti

Per farlo devi avere una vera rappresentazione di Windows. La rappresentazione SPSite non è una vera rappresentazione: indica semplicemente al modello a oggetti WSS di scrivere un altro ID utente nei campi creati e modificati nel database del contenuto.

Sfortunatamente per la rappresentazione di Windows avrai bisogno sia dell'accesso che della password a meno che tu non voglia impersonare l'account del pool di applicazioni usando SPSecurity.RunWithElevatedPrivileges

Puoi implementare la rappresentazione di Windows come segue:

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

dove la classe Impersonator è implementata 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);
}

Esiste effettivamente un altro modo per eseguire la rappresentazione quando si eseguono ricerche utilizzando il modello a oggetti. Sono stato in grado di farlo funzionare facendo impersonificazioni quando correvo con privilegi elevati. vedi il mio post qui: http://vishalseth.com/ dopo / 2013/11/05 / impersonato-Ricerca-contro-SharePoint.aspx

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top