SPSecurityTrimmedControl in Abhängigkeit von SharePoint Gruppen verwenden

SharePoint bietet standardmäßig die Möglichkeit, ein Steuerelement in ein sog. Security Trimmed Control einzubetten, um es lediglich für Benutzer mit einer bestimmten Berechtigung/Permission (z.B. ‘ManageLists’) zur Verfügung zu stellen. Alle anderen Benutzer, die nicht mindestens diese Berechtigung besitzen, bekommen somit den Inhalt des Security Trimmes Controls nicht angezeigt. Die Festlegung der Berechtigung geschieht über das Property “PermissionsString”. So weit so gut!

Problematisch wird es erst, wenn die Bedingung nicht auf der zugewiesenen Berechtigung, sondern anhand der SharePoint Gruppe, in der sich der Benutzer befindet, basieren soll. Hierfür bietet SharePoint leider keine Out-of-the-Box Lösung an. Abhilfe kann in diesem Fall aber die Erstellung eines Custom Controls schaffen, welches von SPSecurityTrimmedControl abgeleitet wird.

Dieses Tutorial soll zeigen, wie man mit Hilfe eines eigenen Controls gezielt Bereiche z.B. aus einem Formular nur für Benutzer einer bestimmten SharePoint Gruppe bereitstellen kann. Für alle anderen Nutzer ist dieser Bereich nicht sichtbar. Konkret soll eine Checkbox im Bearbeiten-Formular (EditForm) nur den Benutzern der Gruppe  “MyCustomGroup” bereitgestellt werden. Dazu sind folgende Schritte notwendig:

  • Custom Control erstellen (abgeleitet von SPSecurityTrimmedControl)
    Dazu ist ein neues SharePoint Projekt in Visual Studio zu erstellen (Farm Solution) und eine Klasse mit folgendem Code hinzuzufügen:
       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Text;
       5:  using System.Web;
       6:  using System.Web.UI;
       7:  using Microsoft.SharePoint.WebControls;
       8:  using Microsoft.SharePoint;
       9:   
      10:  namespace GroupTrimmedControlSolution
      11:  {
      12:          public class GroupTrimmedControl : SPSecurityTrimmedControl
      13:          {
      14:              private List<string> groups = new List<string>();
      15:              public string GroupsString
      16:              {
      17:                  get
      18:                  {
      19:                      return string.Join(",", groups.ToArray());
      20:                  }
      21:                  set
      22:                  {
      23:                      groups.AddRange(value.Split(new char[] { ',' },
      24:                   System.StringSplitOptions.RemoveEmptyEntries)
      25:                          );
      26:                  }
      27:              }
      28:   
      29:              protected override void Render(HtmlTextWriter output)
      30:              {
      31:                  if (!string.IsNullOrEmpty(GroupsString) && IsMember())
      32:                  {
      33:                      base.Render(output);
      34:                  }
      35:              }
      36:   
      37:              private bool IsMember()
      38:              {
      39:                  using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb())
      40:                  {
      41:                      bool isMember = false;
      42:                      foreach (string group in groups)
      43:                      {
      44:                          isMember = web.IsCurrentUserMemberOfGroup(web.Groups[group].ID);
      45:                      }
      46:                      return isMember;
      47:                  }
      48:              }
      49:          }
      50:  }
    Dadurch wird beim Deployment der Solution ein Control namens “GroupTrimmedControl” angelegt, welches später verwendet werden soll. Dieses besitzt ein property namens “GroupsString”, in welches später bei der Implementierung des Controls die benötigte Gruppe eingetragen wird.
  • web.config an zwei Stellen modifizieren
    Damit das Control überhaupt verwendet werden darf, muss es in der web.config als “Safe Control” deklariert werden. Dies geschieht über das einfügen des folgenden Statements.
    <SafeControl 
    Assembly="GroupTrimmedControlSolution, Version=1.0.0.0, Culture=neutral, PublicKeyToken=779b51b95268bfdd"
    Namespace="GroupTrimmedControlSolution"
    TypeName="*"
    Safe="True"
    SafeAgainstScript="False" />
    Die Informationen wie Version, Namespace, PublicKeyToken lassen sich nach dem Build der Solution im Global Assembly Cache (GAC) –> Rechtsklick auf den Namen der Assembly –> Eigenschaften auslesen. 

    Tipp: Alternativ kann Visual Studio auch veranlassen, dass beim Deployment der SafeControl-Eintrag automatisch hinzugefügt wird. Dies geschieht über das Hinzufügen eines neuen Moduls –> Property “SafeControlEntries” –> einen Eintrag hinzufügen (Bild links). Danach taucht der SafeControl-Eintrag direkt in der Manifestdatei der wsp mit auf und man braucht sich nicht mehr um das manuelle Hinzufügen des SafeControl-Eintrags zu kümmern (Bild rechts).
    image image

    Die zweite Modifikation der web.config ist  nur notwendig, wenn das Control auch innerhalb einer WebParts genutzt werden soll. Im Bsp ist dies der Fall, da das Formular zum Bearbeiten von Listemneinträgen (EditForm) ein sog. DataFormWebpart beinhaltet, welches sämtliche Formularsteuerelemente beinhaltet.
    <add tagPrefix="GrpTrimCtrl" 
    namespace="GroupTrimmedControlSolution"
    assembly="GroupTrimmedControlSolution, Version=1.0.0.0, Culture=neutral, PublicKeyToken=779b51b95268bfdd" />

Dieses Statement sorgt dafür, dass der tag-Prefix auch innerhalb des WebParts verwendbar wird.

  • Referenzen in der Masterpage oder der aspx-Page (Formular) einfügen
    Nachdem die Solution nun deployed wurde kann das neue Control innerhalb der Page  verwendet werden. Dazu muss es im Header-Bereich zunächst referenziert werden.
    <%@ Register 
        TagPrefix="GrpTrimCtrl" 
        Namespace="GroupTrimmedControlSolution" 
        Assembly="GroupTrimmedControlSolution, Version=1.0.0.0, Culture=neutral, PublicKeyToken=779b51b95268bfdd" %>
    Auch hier gilt es bei der Verwendung innerhalb des WebParts eine zusätzliche Deklaration im Webpartbereich selbst vorzunehmen. Und zwar muss der Namespace erneut mit dem Präfix verknüpft werden, damit das neue Control von der XSL Transformation verarbeitet werden kann. Folgendes Statement muss innerhalb des xsl:stylesheet Tags eingefügt werden:
    image
     xmlns:GrpTrimCtrl="GroupTrimmedControlSolution"
  • Implemetierung des Custom Controls
    Da nun alle Vorbereitungen getroffen sind, kann das Control an gewünschter Stelle mittels folgendem Statement eingebunden werden:
    <GrpTrimCtrl:GroupTrimmedControl id="hideBelegControl" runat="server" GroupsString="MyCustomGroup">
       <!-- Controls, die betroffen sein sollen -->
    </GrpTrimCtrl:GroupTrimmedControl>
    Im Bsp. sieht das ganze wie folgt aus:
    <GrpTrimCtrl:GroupTrimmedControl id="hideBelegControl" runat="server" GroupsString="MyCustomGroup">
        <tr>
            <td width="190px" valign="top" class="ms-formlabel">
                <H3 class="ms-standardheader">
                    <nobr>BelegeFehlen</nobr>
                </H3>
            </td>
            <td width="400px" valign="top" class="ms-formbody">
                <SharePoint:FormField runat="server" id="ff6{$Pos}" ControlMode="Edit" FieldName="BelegeFehlen" __designer:bind="{ddwrt:DataBind('u',concat('ff6' $Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@BelegeFehlen')}" />
                <SharePoint:FieldDescription runat="server" id="ff6description{$Pos}" FieldName="BelegeFehlen" ControlMode="Edit" />
            </td>
        </tr>
    </GrpTrimCtrl:GroupTrimmedControl>

    Hier wird deutlich, dass eine komplette Zeile mit zwei Spalten und darin enthaltenen Steuerelementen innerhalb der GroupTrimmedControls liegen – und somit für alle Benutzer, die nicht der Gruppe “MyCustomGroup” angehören, ausgeblendet werden.
    Anmerkung: Das Einfügen des ASP Codes für das Control im SharePoint Designer kann zu Problemen führen (in meinem Fall hat er im Start-Tag eine “to lower” case correction vorgenommen, im End-Tag aber nicht –> Ergebnis: Webpart konnte nicht dargestellt werden). Daher bitte ein anderes Tool (ggf. Notepad etc.) verwenden und die aspx-Datei anschließend über den SharePoint Designer oder WebDAV an entsprechende Stelle hochladen.

Schließlich schaut das Ergebnis wie folgt aus. Der Nutzer Max Muster befindet sich in der besagten Gruppe und hat Zugriff auf die im GroupTrimmedControl platzierten Steuerelemente (Bild links). Ein anderer User, der nicht der Gruppe angehört, bekommt das Control samt Inhalt nicht angezeigt (Bild rechts).
image  image

Kommentare sind geschlossen