2009-03-08 10 views
1

J'ai une requête de client pour créer un certain nombre d'annonces basées sur certaines données d'une autre base de données. La plupart d'entre eux semble assez facile mais les nouveaux éléments doivent être créés par l'utilisateur (login) spécifié dans les données d'entrée. Je prévoyais d'ajouter les annonces en utilisant les services Web de liste, mais je voudrais éviter d'utiliser l'emprunt d'identité afin d'obtenir l'utilisateur de créer correctement. Est-il possible d'attribuer l'utilisateur correct en tant que créateur sans utiliser l'emprunt d'identité?Ajouter des éléments à une liste d'annonces pour un utilisateur spécifique

Répondre

2

Cela peut ne pas être la réponse que vous recherchez, mais l'usurpation d'identité est assez facile si vous avez du code en cours d'exécution dans le GAC sur un serveur SharePoint. Vous n'avez pas besoin de connaître un mot de passe que beaucoup ne connaissent pas, donc je continuerai à supposer que c'est la raison pour laquelle vous ne vouliez pas faire d'usurpation d'identité. Voici comment le faire.

Vous pouvez vous connecter à SharePoint en utilisant le constructeur type que vous utilisez pour SPSite et trouver l'objet SPUser approprié. Une fois que vous faites cela, vous pouvez obtenir la propriété UserToken pour ce SPUser. Ensuite, vous devrez utiliser à nouveau le constructeur SPSite, mais utiliser la surcharge fournie par SPUserToken. Tout ce que vous faites dans SharePoint sera ensuite effectué via l'emprunt d'identité. Pas besoin de courir avec des privilèges élevés. OK, maintenant que je l'ai dit en mots, je vais essayer de deviner le code. Il devrait être quelque chose comme:

// Just determine the user token for a particular user 
SPUserToken userToken = null; 
using (SPSite tempSite = new SPSite("http://sharepointurl")) 
{ 
    using (SPWeb tempWeb = tempSite.OpenWeb()) 
    { 
     // I think this next line works, but I'm going from memory 
     // I believe the user needs to have already logged into the site at least once 
     SPUser user = tempWeb.AllUsers["username"]; 
     userToken = user.UserToken; 
    } 
} 

// Now do whatever we want impersonating that user 
using (SPSite site = new SPSite("http://sharepointurl", userToken)) 
{ 
    using (SPWeb web = site.OpenWeb()) 
    { 
     // Do whatever you want here 
    } 
} 
+0

Maintenant que semble intéressant. Je vais essayer et revenir – Kasper

+0

Kirk, je suis stupéfait. L'idée que vous avez proposée fonctionne très bien, mais j'ai d'abord considéré cela comme une vulnérabilité majeure, car la validité de la piste de vérification est maintenant nulle. À la réflexion, je me suis rendu compte que le code hostile devra avoir accès au cœur du système pour utiliser cet «exploit». – Kasper

+0

Oui, moi aussi j'ai été surpris quand j'ai appris que cette faille était là. Comme vous le dites, votre code doit avoir certains niveaux de sécurité d'accès au code (être dans le GAC fait le travail, bien sûr), donc je suppose que ça rend OK :-). Un autre élément intéressant est SPListItem.SystemUpdate(). –

0

Je ne pense pas qu'il existe une méthode pour archiver ceci.

Mais peut-être que cette solution de contournement pourrait aider. Je dois admettre que je n'ai jamais testé ça, c'est juste une idée de comment vous pourriez résoudre votre problème.

Vous pourriez essayer ceci. Créez la nouvelle annonce avec un utilisateur admin ou avec RunWithElevatedPrivileges(). Après cela, utilisez à nouveau la méthode RunWithElevatedPrivileges() et définissez le champ "created by" à l'utilisateur qui devrait être le véritable créateur de l'annonce. De cette façon, seul le champ "édité par" doit montrer le "mauvais" utilisateur.

Je sais que ce n'est pas une solution très élégante, mais cela pourrait fonctionner. ;)

0

Je viens de réaliser que que mon exigence était en fait de contourner la piste d'audit dans SharePoint et j'espère sûr que ce ne peut pas être fait :-)

je suis venu avec une autre solution: j'ai ajouté une nouveau champ d'utilisateur ou de groupe à la liste d'annonces et copiez la connexion de l'utilisateur AD dans ce champ. Tout rapport ou vue qui utilisait précédemment le champ "créé par" devrait maintenant utiliser le nouveau champ.

Que diriez-vous de la situation où un utilisateur réel entre alors un nouvel élément dans la liste d'annonces? Cela ne mettra pas à jour le nouveau champ avec l'utilisateur connecté!

Eh bien, la seule solution que je pourrais proposer est d'ajouter un déclencheur ListItem Add sur la liste. Quand un nouvel élément est ajouté, je vérifie si le nouveau champ contient une valeur, n'est pas alors je mets à jour le nouveau champ avec l'ID de l'utilisateur connecté. De cette façon, le nouveau champ doit toujours contenir un ID utilisateur valide. Je sais que ce n'est pas une solution élégante, mais pour le moment c'est le meilleur que je peux penser.

0

Comme mentionné dans les commentaires du code de réponse, si l'utilisateur n'a pas visité le site au moins une fois, alors il n'y a pas de métadonnées utilisateur disponible à partir de laquelle pour obtenir une UserToken appropriée.

Avec SharePoint 2010, vous pouvez simuler une visite de l'utilisateur, la méthode EnsureUser disponible à partir de la classe SPWeb (cet extrait crée l'utilisateur et tweaks aussi leur profil un peu):

SPUser alice = web.EnsureUser(@"MYDOMAIN\alice"); 
SPList userInfo = web.SiteUserInfoList; //metadata storage of user info 

SPListItem item = userInfo.GetItemById(alice.ID); 
item["About Me"] = "I am Alice from Mel's Diner"; 
item.Update();