Montag, 14. Juli 2008

Probleme beim Updaten von SPFieldLookup-Objekten

Ein Lookup-Feld programmatisch auf eine Liste verlinken ist ein Kinderspiel: einfach die Attribute LookupList mit der GUID der auswählbaren Liste und LookupWebId mit der jeweiligen WebID belegen. Fertig!...

Von wegen! Das ganze funktioniert nämlich nur, solange der aktuelle Benutzer Site Collection Administrator ist.

Wird das von einem User, der nicht Site Collection Administrator ist, angestoßen, kracht es und der Aufruf
spFieldLookup.LookupWebId = spRootWeb.ID;

wirft eine System.UnauthorizedAccessException: Access is denied, bzw. Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)

Eine Lösung für das Problem bietet das SDK durch den Einsatz der Methode SPSecurity.RunWithElevatedPrivileges, der ein delegate übergeben werden kann in dem dann der jeweilige Code ausgeführt wird.

Laut SDK wird die spezifizierte Methode mit FULL CONTROL-Rechten ausgeführt, egal, ob der User diese Rechte besitzt oder nicht.

Ein Beispiel dafür findet sich in der MSDN: *click*

Bei uns sieht das dann in etwa so aus (ich habe ein paar Code-Zeilen der Übersichtlichkeit halber ausgelassen):

SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPWeb site = (SPWeb)properties.Feature.Parent;
SPSite siteColl = site.Site;

// get current site
using (SPSite elevatedSiteColl = new SPSite(siteColl.ID))
{
// get current web
using (SPWeb spCurrentWeb = elevatedSiteColl.OpenWeb(site.ID))
{
// get rootweb from this web's parent site
using (SPWeb spRootWeb = (SPWeb)spCurrentWeb.Site.RootWeb)
{
...anderer code, der z.b. die liste, auf die das lookup-feld referenzieren soll, einlist...

SPFieldLookup spFieldLookup = (SPFieldLookup)spList.Fields.GetFieldByInternalName(lookupInfo.FieldInternalName);
spFieldLookup.LookupWebId = spRootWeb.ID;
spFieldLookup.LookupList = listGuid.ToString();
spFieldLookup.Update();
}
}
}
}
});

Ganz wichtig ist, dass die aktuelle SiteCollection, neu instanziiert wird. Ansonsten wird das SPSite-Objekt des aktuellen Users benutzt was ja ausserhalb des SPSecurity.RunWithElevatedPrivileges-Kontexted generiert wurde und daher keine Berechtigung hat, das Lookup-Feld zu verändern.

Meiner Meinung nach sollte diese Methode wirklich nur an Stellen benutzt werden, an denen es keine Alternative gibt, da sie das Sicherheitskonzept völlig aushebelt und dem Code, der vom aktuellen Benutzer ausgeführt wird, viele Rechte gewährt...

1 Kommentar:

Anonym hat gesagt…

Die lookuplist property sollte eigentlich read-only sein.
Ich versuche schon seit Tage die zu uberschreiben.