6 votes

Peut-on effectuer une recherche par usurpation d'identité dans SharePoint sans fournir de mot de passe ?

J'ai fait l'impersonnalisation dans SharePoint assez souvent dans le passé en faisant quelque chose comme ce qui suit.

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

Notez que cette opération ne nécessite pas le mot de passe de l'utilisateur dont vous vous faites passer pour un autre, mais qu'elle requiert une certaine sécurité d'accès au code pour être exécutée. Par ailleurs, l'appel à EnsureUser nécessite également que l'utilisateur actuel soit un administrateur, mais il existe d'autres méthodes qui peuvent être utilisées à la place de EnsureUser pour obtenir l'objet SPUser (j'essaie de garder mon fragment de code simple pour cette question).

Maintenant que j'ai préparé le terrain... Je veux maintenant faire une FullTextSQLQuery ou une KeywordQuery contre le moteur de requête de MOSS ou WSS et obtenir des résultats triés par sécurité basés sur un utilisateur usurpé. Les deux objets peuvent prendre un SPSite dans le constructeur, mais ignorent ma logique d'usurpation d'identité. Ils utilisent l'utilisateur actuellement connecté à la place (HTTPContext.Current.User).

Il y a aussi d'autres constructeurs : nom de l'application (chaîne) et pour MOSS, il y en a un avec un ServerContext vers le SSP, mais je ne pense pas qu'ils soient d'une quelconque utilité.

J'ai utilisé Reflector sur la classe KeywordQuery et sa classe de base Query et cela devient vite assez moche. Je crois que la logique réelle qui détermine l'utilisateur se trouve dans le code non géré.

Alors, est-ce que c'est possible pour moi de faire ça ?

4voto

Lars Fastrup Points 4155

Pour ce faire, vous avez besoin d'une véritable usurpation d'identité Windows. L'usurpation d'identité SPSite n'est pas une véritable usurpation d'identité - elle indique simplement au modèle d'objet WSS d'écrire un autre identifiant d'utilisateur dans les champs créés et modifiés de la base de données de contenu.

Pour l'usurpation d'identité Windows, vous aurez malheureusement besoin de l'identifiant et du mot de passe, à moins que vous ne souhaitiez usurper l'identité du compte du pool d'applications à l'aide de la fonction SPSecurity.RunWithElevatedPrivileges (Exécuter avec des privilèges élevés)

Vous pouvez mettre en œuvre l'usurpation d'identité Windows comme suit :

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

où la classe Impersonator est implémentée comme :

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);
}

1voto

Kirk Liemohn Points 3489

Il s'avère que vous peut effectuer une recherche usurpée dans SharePoint sans mot de passe. Nous avons trouvé cette solution en août 2009 et j'ai négligé de mettre à jour Stack Overflow avec la réponse.

Véase http://wiki.threewill.com/display/is/2010/06/18/Connect+to+SharePoint+-+Forwarding+User+Identities pour les détails et prêtez une attention particulière aux exigences spécifiques. Notez que cela fonctionne à la fois avec SharePoint 2007 et SharePoint 2010.

Un grand merci à mon collègue Eric Bowden qui a fait tout le travail !

0voto

Vishal Seth Points 1

Il existe en fait une autre façon d'effectuer l'impersonnalisation lors de recherches utilisant le modèle objet. J'ai réussi à la faire fonctionner en faisant l'impersonnalisation avec des privilèges élevés. Voir mon message ici : http://vishalseth.com/post/2013/11/05/Impersonated-Searching-against-SharePoint.aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X