SharePoint 2013 Claims Authentifizierung

Die Standard-Authentifizierung in SharePoint 2013 ist nun die Claims-basierte Authentifizierung. Legt man eine neue Webanwendung an, wird hier standardmäßig diese Authentifizierungsmethode genutzt. Für den Benutzer oder Administrator ist diese Änderung zu SharePoint 2010 fast vollständig transparent. Zumindest solange, bis man Benutzerberechtigungen auf Basis von AD-Gruppen einsetzt. Dann passieren im ersten Moment seltsame Dinge. Man fügt einen Benutzer einer AD-Gruppe hinzu, aber trotzdem hat der Benutzer keine entsprechende Berechtigung im SharePoint. Weist man dem Benutzer direkte Berechtigungen zu, funktioniert es einwandfrei. Analog ist das Verhalten, wenn man einen Benutzer aus einer AD-Gruppe entfernt: Obwohl der Nutzer nicht mehr in der AD-Gruppe ist, hat er noch die zugehörigen Berechtigungen im SharePoint. Das Ganze wird noch merkwürdiger, wenn das Vorgehen mit AD-Gruppen bei anderen Benutzer einwandfrei funktioniert.

Allerdings ist es wie meistens in der IT-Welt nicht ein willkürliches Verhalten vom System um die Administratoren zu ärgern, sondern mit ein bisschen Hintergrundwissen einfach nachzuvollziehen.

Die Claims-basierte Authentifizierung tickt nämlich ein bisschen anders als die bisher in SharePoint verwendete klassische Authentifizierung.

Eine vereinfachte Sicht wie SharePoint mit diesen Tokens umgeht, sieht folgendermaßen aus:

  1. Ein Benutzer ruft eine SharePoint Seite auf.
  2. SharePoint prüft den lokalen STS (Security Token Service) auf gültige zwischengespeicherte Claims (beinhaltet auch die Gruppenzugehörigkeiten) für den Benutzer.
  3. Wenn kein Claim vorhanden ist, werden vom STS ein neue Claims erstellt und zwischengespeichert. Dazu frägt der STS das AD ab.
  4. Ist allerdings ein gültiger Claim für den Benutzer zwischengespeichert, wird dieser verwendet.

Dies ist der vereinfachte Ablauf wie die Authentifizierung in SharePoint 2013 funktioniert. Jetzt stellt sich die Frage wie die Gültigkeitsdauer der zwischengespeicherten Claims geändert werden kann. Die standardmäßige Gültigkeit für diesen Cache liegt bei 24 Stunden. Diese kann durch folgenden PowerShell Befehl geändert werden:

$cs = [Microsoft.SharePoint.Administration.SPWebservice]::ContentService
$cs.TokenTimeout = (New-Timespan -Minutes 5)
$cs.Update()

Somit bekommt der SharePoint die Änderungen bzgl. AD-Gruppen-Berechtigungen alle 5 Minuten mit.  Allerdings gilt diese Einstellung nur für neu ausgestellte Tokens. Bereits im Cache befindliche Tokens sind hiervon unberührt. Somit kann es immer noch zu dazu kommen, dass die Berechtigungen für die Benutzer nicht synchron mit den Gruppenmitgliedschaften im AD sind. Um dies noch zu ändern, muss die Konfiguration vom STS angepasst werden. Die standardmäßige Gültigkeitsdauer für diese Tokens beträgt 10 Stunden. Die aktuelle Konfiguration vom STS kann man sich über PowerShell ansehen:

Relevant sind dabei die zwei folgenden Werte:

  1. WindowsTokenLifetime: Gültigkeitsdauer für ausgestellte Tokens von Windows-Benutzern (in Minuten). (Für Formular-basierte Authentifizierung gilt der Wert von FormsTokenLifetime, das Vorgehen und Funktionsweise ist identisch.)
  2. LogonTokenCacheExpirationWindow: SharePoint prüft ob der Sicherheits-Token abgelaufen ist und fordert ein neues Token an. SharePoint prüft die Gültigkeit vom Token am Anfang von jedem Request (in Minuten).

Aber warum gibt es jetzt zwei Werte, die plötzlich für die Gültigkeitsdauer relevant sind? Dazu ein einfaches Beispiel, um es zu verdeutlichen:

WindowsTokenLifetime = 10
LogonTokenCacheExpirationWindow = 5

RenewTokenAfter = WindowsTokenLifetime - LogonTokenCacheExpirationWindow = 10 - 5 = 5

Mit dieser Konfiguration ist SharePoint der Meinung, dass alle 5 Minuten der Token erneuert werden muss. Allerdings muss man beachten: WindowsTokenLifeTime > LogonTokenCacheExpirationWindows. Ansonsten werden in einer Endlosschleife neue Tokens generiert und die Benutzer können sich nicht mehr einloggen. Weiterhin ist es empfohlen ContentServiceTimeOutWindowsTokenLifeTime > LogonTokenCacheExpirationWindows zu wählen.

Die Änderung der beiden Werte funktioniert analog wie bereits oben beschrieben:

$sts = Get-SPSecurityTokenServiceConfig
$sts.WindowsTokenLifetime = (New-TimeSpan -minutes 10)
$sts.LogonTokenCacheExpirationWindow = (New-TimeSpan -minutes 5)
$sts.Update()
iisreset /noforce

Die definierten Zeitwerte sollten allerdings nicht zu klein gewählt werden. Je kleiner die Gültigkeitsdauer definiert ist, umso mehr Abfragen (=Netzwerk-Traffic) werden Richtung AD gesendet. Die oben genannten Beispielwerte sind sehr klein gewählt und für einen produktiven Betrieb eher ungeeignet. Hier sollte der Administrator einen stabilen Mittelwert finden, der je nach Umgebung unterschiedlich ausfallen kann.

Weiterhin gibt es auch eine Quick & Dirty Möglichkeit, sich die Claims von einem Benutzer anzeigen zu lassen. Hierfür benötigt man eine ASPX-Datei mit folgendem Inhalt, die im _layouts Ordner vom SharePoint abgespeichert wird:

<%@ Page Language="C#" %>
<%@ Assembly Name="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" %>
<%@ Import Namespace="Microsoft.IdentityModel.Claims" %>

<script type="text/C#" runat="server">
    protected override void OnLoad(EventArgs e)
    {
        try
        {
            IClaimsIdentity identity = HttpContext.Current.User.Identity as IClaimsIdentity;

            if (null != identity)
            {
                repeater1.DataSource = identity.Claims;
                repeater1.DataBind();
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
    }
</script>

<html>
    <body>
        <table>
            <thead>
                <tr>
                    <td><strong>Issuer</strong></td>
                    <td><strong>OriginalIssuer</strong></td>
                    <td><strong>ClaimType</strong></td>
                    <td><strong>Subject</strong></td>
                    <td><strong>Value</strong></td>
                    <td><strong>ValueType</strong></td>
                </tr>
            </thead>
            <tbody>
                <asp:Repeater ID="repeater1" runat="server">
                    <ItemTemplate>
                        <tr>
                            <td><nobr><%# Eval("Issuer") %></nobr></td>
                            <td><nobr><%# Eval("OriginalIssuer") %></nobr></td>
                            <td><nobr><%# Eval("ClaimType") %></nobr></td>
                            <td><nobr><%# Eval("Subject") %></nobr></td>
                            <td><nobr><%# Eval("Value") %></nobr></td>
                            <td><nobr><%# Eval("ValueType") %></nobr></td>
                        </tr>
                    </ItemTemplate>
                </asp:Repeater>
            </tbody>
        </table>
    </body>
</html>

Wenn man diese Datei nun über den Browser aufruft, werden die Claims des aktuellen Benutzers ausgegeben. Das Resultat kann zum Beispiel so aussehen:

Die zugehörigen AD-Gruppen sind im Beispiel hervorgehoben. Logischerweise werden die AD-Gruppen mit ihrem Security Identifier (SID) angezeigt/gespeichert. Um die SID in einen lesbaren Gruppennamen umzuwandeln, gibt es eine Vielzahl von Möglichkeiten. Eine recht einfache Methode wäre zum Beispiel der Einsatz eines Third-Party-Tools wie Sid2UserName.

Mit dem hier aufgeführtem Wissen ist die Claims-basierte Authentifizierung gar nicht mehr so merkwürdig und auch das am Anfang beschriebene Verhalten macht auf einmal Sinn. Somit ist man für weiteres Debugging bzgl. Claims bestens gerüstet.

Happy SharePointing…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert