Autorisierungscode-OAuth-Fluss für SharePoint-Add-Ins

Hinweis

In diesem Artikel wird davon ausgegangen, dass Sie mit dem Erstellen von SharePoint-Add-Ins, die die Autorisierung mit niedriger Vertrauensebene verwenden, und den Konzepten und Prinzipien von OAuth vertraut sind. Weitere Informationen zu OAuth finden Sie unter OAuth.net und Webautorisierungsprotokoll (oauth).

Wichtig

Azure ACS (Access Control), ein Dienst von Azure Active Directory (Azure AD), wird am 7. November 2018 eingestellt. Diese Deaktivierung wirkt sich nicht auf das SharePoint-Add-In-Modell aus, das den https://accounts.accesscontrol.windows.net Hostnamen verwendet (was von dieser Deaktivierung nicht betroffen ist). Weitere Informationen finden Sie unter Auswirkungen der Deaktivierung von Azure Access Control für SharePoint-Add-Ins.

In einigen Szenarien kann ein Add-In die Berechtigung für den Zugriff auf SharePoint-Ressourcen im laufenden Betrieb anfordern, d. h. dass ein Add-In die Berechtigung für den Zugriff auf SharePoint-Ressourcen dynamisch zur Laufzeit anstatt bei der Installation des Add-Ins anfordern kann. Diese Art von Add-In muss nicht aus SharePoint gestartet und auch nicht auf SharePoint installiert werden. Es kann sich beispielsweise um ein natives Gerät-Add-In handeln, also ein Add-In, das von einer beliebigen Website gestartet wird, oder um ein Office-Add-In, das über eine Office-Anwendung gestartet wird und im laufenden Betrieb auf Ressourcen in SharePoint zugreifen möchte.

Hinweis

Dieser Add-In-Typ kann nur von Benutzern mit Verwaltungsberechtigungen für die Ressourcen ausgeführt werden, auf die das Add-In zugreifen möchte. Wenn ein Add-In beispielsweise nur die Leseberechtigung für eine Website anfordert, kann ein Benutzer das Add-In mit der Berechtigung "Lesen" ohne die Berechtigung "Verwalten" nicht ausführen.

Um sich in SharePoint einwählen können, muss diese Art von Add-In zunächst über das Händler-Dashboard oder die Seite AppRegNew.aspx registriert werden. Weitere Informationen zum Registrieren von Add-Ins über das Händler-Dashboard oder AppRegNew.aspx finden Sie unter Registrieren von SharePoint-Add-Ins.

Nachdem Sie das Add-In registriert haben, ist es ein Sicherheitsprinzipal und verfügt wie Benutzer und Gruppen über eine Identität. Diese Identität wird als Add-In-Prinzipal bezeichnet. Wie Benutzer und Gruppen besitzt ein Add-In-Prinzipal bestimmte Berechtigungen. Weitere Informationen über Add-In-Prinzipale finden Sie unter Registrieren von SharePoint-Add-Ins.

Wenn Sie das Add-In registrieren, erhalten Sie eine Client-ID, einen geheimen Clientschlüssel, eine Add-In-Domäne und einen Umleitungs-URI für den Add-In-Prinzipal. Diese Informationen werden beim Autorisierungsserver, winazureacslong, registriert.

Autorisierungscode-OAuth-Ablauf für Add-Ins, die Berechtigungen dynamisch anfordern

Dieser Abschnitt fasst den OAuth-Authentifizierungs- und Autorisierungsablauf für ein SharePoint-Add-In zusammen, das Berechtigungen im laufenden Betrieb anfordert. Dieser Ablauf wird als Autorisierungscode-Ablauf bezeichnet. Die Sequenz beschreibt, wie ein Add-In, das nicht aus SharePoint gestartet wird, auf Ressourcen in SharePoint zugreifen kann.

Hinweis

Der Ablauf umfasst eine Reihe von Interaktionen zur Laufzeit zwischen Ihrem Add-In, SharePoint, dem Server für die Autorisierung (ACS) und dem Endbenutzer. Der Ablauf benötigt entweder SharePoint Online oder eine SharePoint-Farm, die mit dem Internet verbunden ist, um mit ACS kommunizieren zu können. SharePoint-Farmen, die nicht mit dem Internet verbunden sind, müssen das Autorisierungssystem mit hoher Vertrauenswürdigkeit verwenden.

Es muss eine Webanwendung oder ein Webdienst vorhanden sein, die bzw. der separat von SharePoint gehostet wird. Auch wenn es sich bei dem Add-In um ein Gerät-Add-In handelt, muss es über eine Webanwendung oder Dienst-URL verfügen, die mit ACS registriert werden kann, auch wenn die Webkomponente für nichts anderes verwendet wird.

Der Einfachheit halber wird in diesem Artikel davon ausgegangen, dass das Add-In eine Webanwendung namens „Contoso.com“ ist. Die Anwendung verwendet das SharePoint-Clientobjektmodell (CSOM) oder die SharePoint-REST-APIs für Aufrufe an SharePoint. Wenn die Anwendung erstmalig versucht, auf SharePoint zuzugreifen, fordert SharePoint einen Autorisierungscode von ACS an, um diesen an die Anwendung Contoso.com zu senden. Die Anwendung verwendet dann den Autorisierungscode, um ein Zugriffstoken bei ACS anfordern. Nachdem die Anwendung Contoso.com das Zugriffstoken erhalten hat, fügt sie es in alle Anfragen an SharePoint ein.

Ausführliches Beispiel des Ablaufs

Nehmen wir an, dass Contoso einen Online-Fotodruckdienst bereitstellt. Ein Benutzer möchte einige Fotos drucken. Der Benutzer möchte es dem Fotodruckdienst von Contoso ermöglichen, auf Fotos in unterschiedlichen Fotobibliotheken zuzugreifen, die der Benutzer auf einer SharePoint Online-Website, fabrikam.sharepoint.com, aufbewahrt, und diese zu drucken.

Übersicht über OAuth

Die Fotodruck-Anwendung ist registriert, daher verfügt sie über eine Client-ID, einen geheimen Clientschlüssel und einen Umleitungs-URI. Der Umleitungs-URI, den Contoso bei der Registrierung der Add-In bereitgestellt hat, lautet https://contoso.com/RedirectAccept.aspx. Die Informationen zur Client-ID und zum geheimen Clientschlüssel werden in der Datei web.config der Fotodruck-Anwendung gespeichert. Es folgt ein Beispiel dazu, wie die Client-ID und der geheime Clientschlüssel in die Datei web.config eingetragen werden.

<configuration>
  <appSettings>
    <add key="ClientId" value="c78d058c-7f82-44ca-a077-fba855e14d38 "/>
    <add key="ClientSecret" value="SbALAKghPXTjbBiLQZP+GnbmN+vrgeCMMvptbgk7T6w= "/>
  </appSettings>
</configuration>

Schritte Autorisierungscode-Ablaufs

Im Folgenden sind die Schritte des Autorisierungscode-Ablaufs aufgeführt.

Tipp

Diese Schritte beziehen sich auf Methoden in der Datei TokenHelper.cs. Dieser verwaltete Code wird nicht kompiliert, daher gibt es dafür keine Themen mit Referenzinformationen. Die Datei selbst wurde jedoch vollständig mit Beschreibungen der einzelnen Klassen, Elementparameter und Rückgabewerte kommentiert. Es bietet sich an, eine Kopie der Datei zur Referenz geöffnet zu haben, während Sie die folgenden Schritte lesen.

Schritt 1: Der Client öffnet eine Anwendung und leitet sie an eine SharePoint-Website für Daten um.

Dreisäuliger OAuth-Fluss – Schritt 1

Ein Benutzer öffnet die Contoso-Fotodruck-Website und findet auf der Benutzeroberfläche den Hinweis, dass er Fotos drucken kann, die auf einer beliebigen SharePoint Online-Website aufbewahrt werden.

In diesem Beispiel ist die URL https://contoso.com/print/home.aspx

Das Fotodruck-Add-In fordert den Benutzer zur Eingabe der URL der Fotosammlung auf. Der Benutzer gibt eine URL ein, die auf die SharePoint Online-Website verweist: https://fabrikam.sharepoint.com/

Schritt 2: Das Add-In wird an die Autorisierungs-URL der SharePoint-Website weitergeleitet.

Dreisäuliger OAuth-Fluss – Schritt 2

Wenn der Benutzer die Schaltfläche zum Abrufen der Fotos auswählt, leitet das Contoso-Fotodruck-Add-In den Browser an https://fabrikam.sharepoint.com/ um. Diese Umleitung ist eine HTTP-302-Umleitungsantwort.

Wenn Sie Microsoft .NET verwenden, ist Response.Redirect eine von mehreren Methoden, mit denen Sie die Umleitung aus Ihrem Code ausführen können. Wenn Sie die TokenHelper.cs-Datei in Ihrem Projekt verwenden, kann Ihr Code die überladene GetAuthorizationUrl-Methode aufrufen (mit der Überladung mit drei Argumenten). Durch diese Methode wird die Umleitungs-URL für OAuthAuthorize.aspx automatisch erstellt. Sie können den Code aber auch manuell erstellen.

Wenn Sie beispielsweise die GetAuthorizationUrl-Methode aufrufen, um die OAuthAuthorize.aspx-Umleitungs-URL automatisch zu erstellen, ergibt sich bei Verwendung der Datei TokenHelper.cs in Ihrem Projekt folgender Code:

Response.Redirect(
  TokenHelper.GetAuthorizationUrl(
    sharePointSiteUrl.ToString(),
    "Web.Read List.Write",
    "https://contoso.com/RedirectAccept.aspx"
  )
);

Wenn Sie sich die Überlastungsliste der drei Parameter der GetAuthorizationUrl-Methode in TokenHelper.cs ansehen, werden Sie feststellen, dass der zweite Parameter ein Berechtigungsbereich-Parameter ist, bei dem es sich um eine durch Leerzeichen getrennte Liste von Berechtigungen handelt, die das Add-In im Kurzschriftformat anfordert. Weitere Informationen zu Berechtigungsbereichen finden Sie unter Berechtigungsbereichsaliasen und die Verwendung der OAuthAuthorize.aspx-Seite.

Der dritte Parameter muss der gleiche Umleitungs-URI sein, der bei der Registrierung des Add-Ins verwendet wurde. Weitere Informationen zur Registrierung finden Sie unter Registrieren von SharePoint-Add-Ins. Die zurückgegebene Zeichenfolge ist eine URL, einschließlich der Parameter der Abfragezeichenfolge. Sie können die OAuthAuthorize.aspx-Umleitungs-URL aber auch manuell erstellen. Beispielsweise lautet die URL, zu der das Contoso-Fotodruck-Add-In den Benutzer umleitet in diesem Fall (Zeilenumbrüche für bessere Lesbarkeit hinzugefügt):

https://fabrikam.sharepoint.com/_layouts/15/OAuthAuthorize.aspx?
    client_id=client_GUID
    &scope=app_permissions_list
    &response_type=code
    &redirect_uri=redirect_uri

Wie im Beispiel zu sehen, sendet das Contoso-Fotodruck-Add-In die OAuth-Client-ID und den Umleitungs-URI als Abfragezeichenfolge-Parameter an die Fabrikam-Website. Es folgt ein Beispiel für die GET-Anforderung mit Beispielwerten für die Abfragezeichenfolge. Die tatsächlichen Ziel-URL ist eine einzelne Zeile.

GET /_layouts/15/OAuthAuthorize.aspx?client_id=c78d058c-7f82-44ca-a077-fba855e14d38&scope=list.read&response_type=code&redirect_uri=https%3A%2F%2Fcontoso%2Ecom%2Fredirectaccept.aspx HTTP/1.1
Host: fabrikam.sharepoint.com

Wenn Sie ein separates Popupfenster zum Einholen der Zustimmung verwenden möchten, können Sie dem URL-Konstrukt den Abfrageparameter IsDlg=1 hinzufügen, wie hier gezeigt: /oauthauthorize.aspx?IsDlg=1&client_id=c78d058c-7f82-44ca-a077-fba855e14d38&scope=list.read&response_type=code&redirect_uri=https%3A%2F%2Fcontoso%2Ecom%2Fredirectaccept.aspx

Dreisäuliger OAuth-Fluss – Schritt 3

Falls der Benutzer noch nicht bei der Fabrikam-SharePoint Online-Website angemeldet ist, wird er aufgefordert, sich anzumelden. Ist der Benutzer bereits angemeldet, wird eine HTML-Zustimmungsseite von SharePoint gerendert. Die Zustimmungsseite fordert den Benutzer auf, dem Contoso-Fotodruck-Add-In die Berechtigungen zu erteilen (oder zu verweigern), die das Add-In anfordert. In diesem Fall gewährt der Benutzer dem Add-In den Lesezugriff auf die Bildbibliothek des Benutzers auf Fabrikam.

Schritt 4: SharePoint fordert bei ACS einen kurzfristigen Autorisierungscode an.

Dreisäuliger OAuth-Fluss – Schritt 4

Die Fabrikam-SharePoint Online-Website fordert den Zugriffssteuerungsdienst auf, für diese Kombination aus Benutzer und Add-In einen kurzfristigen (ca. 5 Minuten gültigen) eindeutigen Autorisierungscode zu erstellen. ACS sendet den Autorisierungscode an die Fabrikam-Website.

Schritt 5: Die SharePoint Online-Website wird an den registrierten Umleitungs-URI des Add-Ins weitergeleitet und übergibt dabei den Autorisierungscode an das Add-In.

Dreisäuliger OAuth-Fluss – Schritt 5

Die Fabrikam-SharePoint Online-Website leitet den Browser über die Antwort HTTP 302 zurück zu Contoso. Das URL-Konstrukt für diese Umleitung verwendet den Umleitungs-URI, der bei der Registrierung des Fotodruck-Add-Ins angegeben wurde. Es beinhaltet zudem den Autorisierungscode als Abfragezeichenfolge.

Die Umleitungs-URL ist folgendermaßen strukturiert: https://contoso.com/RedirectAccept.aspx?code=[authcode]

Schritt 6: Das Add-In verwendet den Autorisierungscode, um bei ACS ein Zugriffstoken anzufordern. ACS validiert die Anforderung, macht den Autorisierungscode ungültig und sendet dann Zugriffs- und Aktualisierungstoken dann an das Add-In.

Dreisäuliger OAuth-Fluss – Schritt 6

Contoso ruft den Autorisierungscode aus dem Abfrageparameter ab und fügt ihn dann zusammen mit der Client-ID und dem geheimen Clientschlüssel in eine Anforderung an ACS für ein Zugriffstoken ein.

Wenn Sie verwalteten Code und SharePoint CSOM, die Datei TokenHelper.cs verwenden, lautet die Methode für die Anforderung an ACS GetClientContextWithAuthorizationCode. In diesem Fall sieht der Code in etwa wie folgt aus (wobei authCode eine Variable ist, der der Autorisierungscode zugewiesen wurde):

TokenHelper.GetClientContextWithAuthorizationCode(
  "https://fabrikam.sharepoint.com/",
  "00000003-0000-0ff1-ce00-000000000000",
  authCode,
  "1ee82b34-7c1b-471b-b27e-ff272accd564",
  new Uri(Request.Url.GetLeftPart(UriPartial.Path))
);

Wenn Sie sich die Datei TokenHelper.cs ansehen, ist der zweite Parameter der GetClientContextWithAuthorizationCode-Methode dertargetPrincipalName. Dieser Wert ist immer die Konstante 00000003-0000-0ff1-ce00-000000000000 in einem Add-In, das auf SharePoint zugreift. Wenn Sie die Anrufhierarchie von GetClientContextWithAuthorizationCode nachverfolgen, sehen Sie die Client-ID und den Schlüssel aus der Datei web.config.

ACS erhält die Anforderung von Contoso und überprüft die Client-ID, den geheimen Clientschlüssel, den Umleitungs-URI und den Autorisierungscode. Wenn alle gültig sind, macht ACS den Autorisierungscode ungültig (er kann nur einmal verwendet werden) und erstellt ein Aktualisierungstoken und ein Zugriffstoken, die an Contoso zurückgegeben werden. Die Contoso-Anwendung kann diesen Zugriffstoken für die Wiederverwendung bei späteren Anfragen zwischenspeichern. Standardmäßig sind Zugriffstoken 12 Stunden gültig.

Jedes Zugriffstoken gilt nur für das Benutzerkonto, das in der ursprünglichen Anforderung für die Autorisierung angegeben ist, und gewährt nur auf die Dienste Zugriff, die in dieser Anforderung festgelegt wurden. Das Add-In sollte das Zugriffstoken sicher speichern. Die Contoso-Anwendung kann auch das Aktualisierungstoken zwischenspeichern. Standardmäßig sind Aktualisierungstoken sechs Monate gültig. Das Aktualisierungstoken kann gegen ein neues Zugriffstoken von ACS eingetauscht werden, bis das Aktualisierungstoken abläuft.

Ausführliche Informationen zu Token finden Sie unter Handhabung von Sicherheitstoken in vom Anbieter gehosteten Add-Ins für SharePoint mit niedriger Vertrauensebene.

Schritt 7: Das Add-In kann jetzt das Zugriffstoken verwenden, um Daten von der SharePoint-Website anzufordern, die sie dem Benutzer anzeigen kann.

Dreisäuliger OAuth-Fluss – Schritt 7

Contoso schließt das Zugriffstoken ein, um eine REST-API- oder CSOM-Aufforderung an SharePoint durchzuführen und übergibt dabei das OAuth-Zugriffstoken im HTTP- Authorization-Header. SharePoint gibt die von Contoso angeforderten Informationen zurück.

Ausführliche Informationen zur Durchführung dieser Anforderung finden Sie unter Handhabung von Sicherheitstoken in vom Anbieter gehosteten Add-Ins mit niedriger Vertrauensebene für SharePoint.

Aliase für Berechtigungsbereiche und Verwendung der OAuthAuthorize.aspx-Seite

In diesem Abschnitt wird davon ausgegangen, dass Sie mit dem Artikel Add-In-Berechtigungen in SharePoint vertraut sind. In Tabelle 1 sind dieselben URIs für den Add-In-Berechtigungsanforderungsbereich aufgeführt wie in diesem Artikel, mit der Ausnahme, dass die Tabelle über eine zusätzliche Spalte (Bereichsalias) verfügt und das Recht "FullControl" nicht in der Spalte Verfügbare Rechte verfügbar ist, da ein Add-In, das die Berechtigung für den Zugriff auf SharePoint-Ressourcen dynamisch anfordert, keinen Vollzugriff anfordern kann.

Die in der Spalte Bereichsalias aufgelisteten Werte sind Kurzformen ihrer Entsprechungen in der Spalte Bereichs-URI. Die Aliase können nur von Add-Ins verwendet werden, die die Berechtigung für den Zugriff auf SharePoint-Ressourcen im laufenden Betrieb anfordern. (Die Bereichs-URI-Werte werden im Add-In-Manifest von Add-Ins verwendet, die von SharePoint gestartet werden. Diese Add-Ins fordern während der Installation des Add-Ins Berechtigungen an.)

Die Bereichsaliase kommen nur im Rahmen der Verwendung der OAuthAuthorize.aspx-Umleitungsseite zum Einsatz. Wie in Schritt 2 des im vorherigen Abschnitt beschriebenen OAuth-Ablaufs gezeigt, werden die Aliase, wenn das Add-In verwalteten Code verwendet, beim Aufrufen der GetAuthorizationUrl-Methode von TokenHelper.cs in Ihrem Projekt benutzt. Es folgt ein weiteres Beispiel.

Response.Redirect(TokenHelper.GetAuthorizationUrl(
    sharePointSiteUrl.ToString(),
    "Web.Read List.Write ",
    "https://contoso.com/RedirectAccept.aspx ")
);

Der Bereich-Parameterwert, Web.Read List.Write, ist ein Beispiel dafür, wie Sie Berechtigungen mithilfe der Bereichsaliasen anfordern würden. Der Bereich-Parameter ist ein durch Leerzeichen getrennter Satz von Berechtigungsbereich- und Berechtigungsanfragen.

Wenn Sie keinen verwalteten Code verwenden, werden die Bereichsaliase im Bereichsfeld der Umleitungs-URL verwendet. Zum Beispiel:

https://fabrikam.sharepoint.com/_layout/15/OAuthAuthorize.aspx?client_id=c78d058c-7f82-44ca-a077-fba855e14d38&scope=list.write&response_type=code&redirect_uri=https%3A%2F%2Fcontoso%2Ecom%2Fredirectaccept.aspx

Hinweis

Eine Beschreibung der Bereiche finden Sie unter Add-In-Berechtigungen in SharePoint.

Tabelle 1. URIs für SharePoint-Add-In-Berechtigungsanforderungsbereiche und die entsprechenden Aliase

Bereichs-URI Bereichsalias Verfügbare Rechte
https://sharepoint/content/sitecollection Website Read, Write, Manage
https://sharepoint/content/sitecollection/web Web Read, Write, Manage
https://sharepoint/content/sitecollection/web/list Liste Read, Write, Manage
https://sharepoint/content/tenant AllSites Read, Write, Manage
https://sharepoint/bcs/connection Keine (wird derzeit nicht unterstützt) Read
https://sharepoint/search Suche QueryAsUserIgnoreAppPrincipal
https://sharepoint/projectserver ProjectAdmin Verwalten
https://sharepoint/projectserver/projects Projekte Read, Write
https://sharepoint/projectserver/projects/project Project Read, Write
https://sharepoint/projectserver/enterpriseresources ProjectResources Read, Write
https://sharepoint/projectserver/statusing ProjectStatusing SubmitStatus
https://sharepoint/projectserver/reporting ProjectReporting Read
https://sharepoint/projectserver/workflow ProjectWorkflow Elevate
https://sharepoint/social/tenant AllProfiles Read, Write, Manage
https://sharepoint/social/core Sozial Read, Write, Manage
https://sharepoint/social/microfeed MicroFeed Read, Write, Manage
https://sharepoint/taxonomy TermStore Read, Write

Umleitungs-URIs und Beispiel-Umleitungsseiten

Der Umleitungs-URI, der von Add-Ins verwendet wird, die Berechtigungen im laufenden Betrieb anfordern, ist der URI, zu dem SharePoint den Browser umleitet, nach dem eine Zustimmung gewährt wurde (mit dem Autorisierungscode als Abfrageparameter inbegriffen). Schritt 2 des OAuth-Ablaufs bietet ein Beispiel, in dem der URI in einer Abfrage an die GetAuthorizationUrl-Methode hartcodiert ist. Alternativ kann ein ASP.NET-Add-In den Umleitungs-URI auch in der Datei web.config speichern, wie im folgenden Beispiel gezeigt:

<configuration>
  <appSettings>
    <add key="RedirectUri" value="https://contoso.com/RedirectAccept.aspx" />
  </appSettings>
<configuration>

Der Wert kann mit einem Aufruf von WebConfigurationManager.AppSettings.Get("RedirectUri") abgerufen werden.

Der Endpunkt des RedirectUri-URI erhält den Autorisierungscode vom Abfrageparameter und verwendet ihn, um ein Zugriffstoken zu erhalten, das dann für den Zugriff auf SharePoint verwendet werden kann. In der Regel ist der Endpunkt dieselbe Seite oder Controllermethode oder Webmethode, die ursprünglich versucht hat, auf SharePoint zuzugreifen. Es kann jedoch auch eine Seite oder eine Methode sein, die nur das Autorisierungstoken erhält und dann an eine andere Seite oder Methode umleitet. Die besondere Seite oder Methode kann das Autorisierungstoken weitergeben oder zwischenspeichern. (Es besitzt eine Lebensdauer von ca. 5 Minuten). Alternativ kann sie das Autorisierungstoken verwenden, um ein Zugriffstoken abzurufen, das dann zwischengespeichert wird.

Wichtig

RedirectUri muss dem Endpunkt entsprechen, der beim Erstellen der App auf der Seite AppRegNew.aspx aufgelistet wurde.

Im Folgenden finden Sie ein Beispiel für den Code hinter einer solchen Seite in einer ASP.NET-Anwendung. Anmerkungen zu diesem Code:

  • Er verwendet die Datei TokenHelper.cs, die von den Office-Entwicklertools für Visual Studio generiert wird.
  • Der Code geht davon aus, dass es einen "Code"-Abfrageparameter gibt, der einen Autorisierungscode enthält. Dies ist sicher, da die Seite nur von SharePoint und nur bei Übergabe eines Autorisierungscodes aufgerufen wird.
  • Er verwendet das CSOM-Clientkontextobjekt, um auf SharePoint zuzugreifen, könnte dieses Objekt aber auch auf dem Server zwischengespeichert und an eine andere Seite weitergeleitet haben.
  • Die GetClientContextWithAuthorizationCode-Methode verwendet den Autorisierungscode, um einen Zugriffscode abzurufen. Anschließend erstellt sie ein SharePoint-Clientkontextobjekt und ändert den Ereignishandler für das ExecutingWebRequest-Ereignis, damit der Handler das Zugriffstoken in alle Anfragen an SharePoint einbezieht. Das Zugriffstoken wird innerhalb des Objekts zwischengespeichert.
  • Die GetClientContextWithAuthorizationCode-Methode sendet die Umleitung-URL im rUrl-Parameter zurück an ACS, das sie jedoch als eine Form der Identifikation verwendet, falls der Autorisierungscode gestohlen wurde. ACS verwendet sie jedoch nicht, um eine erneute Umleitung durchzuführen, damit dieser Code keine Umleitungsendlosschleife an sich selbst durchführt.
  • Der Code kann abgelaufene Zugriffstoken nicht verarbeiten. Nachdem das Clientkontextobjekt erstellt wurde, verwendet es das gleiche Zugriffstoken. Das Aktualisierungstoken wird nicht vom Clientkontextobjekt verwendet. Dies ist eine geeignete Strategie für Add-Ins, die nur in Sitzungen verwendet werden, die kürzer Dauern als die Lebensdauer eines Zugriffstokens.

Ein komplexeres Beispiel zur Verwendung des Aktualisierungstoken zum Abrufen eines neuen Zugriffstokens finden Sie im nächsten Abschnitt.

public partial class RedirectAccept : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    string authCode = Request.QueryString["code"];
    Uri rUri = new Uri("https://contoso.com/RedirectAccept.aspx");

    using (ClientContext context = TokenHelper.GetClientContextWithAuthorizationCode(
        "https://fabrikam.sharepoint.com/",
        "00000003-0000-0ff1-ce00-000000000000",
        authCode,
        "1ee82b34-7c1b-471b-b27e-ff272accd564".
        rUri))
    {
      context.Load(context.Web);
      context.ExecuteQuery();

      Response.Write("<p>" + context.Web.Title + "</p>");
    }
  }
}

Zugrunde liegender Beispielcode für eine Seite, die auf SharePoint zugreift

Im Folgenden sehen Sie den Code, der einer Default.aspx-Seite zugrunde liegt. Diese Seite geht von einem Szenario aus, in dem die Default-Seite die Startseite für das Add-In und außerdem die registrierte Umleitungs-URL für das Add-In ist. Anmerkungen zu diesem Code:

  • Die Page_Load-Methode überprüft zuerst, ob die Abfragezeichenfolge einen Autorisierungscode enthält. Es ist ein Autorisierungscode vorhanden, wenn der Browser von SharePoint auf die Seite umgeleitet wurde. Wenn ein Autorisierungscode vorhanden ist, verwendet der Code ihn, um ein neues Aktualisierungstoken abzurufen, das für die Dauer der Sitzung in einem permanenten Cache zwischengespeichert wird.

  • Die Methode überprüft dann, ob ein Aktualisierungstoken im Cache vorhanden ist.

    • Liegt keines vor, wird ein solches erhalten, indem SharePoint die erforderlichen Berechtigungen mitgeteilt werden (Schreibberechtigung im Webbereich) und von SharePoint ein Autorisierungscode angefordert wird. Der Benutzer wird aufgefordert, die Berechtigung zu erteilen, und wenn er dies tut, ruft SharePoint den Autorisierungscode aus ACS ab und sendet ihn als Abfrageparameter bei einer Umleitung zu dieser Seite zurück.
    • Liegt ein zwischengespeichertes Aktualisierungstoken vor, verwendet die Methode es, um ein Zugriffstoken direkt von ACS abzurufen. Wie im Beispiel am Ende des vorhergehenden Abschnitts des Artikels wird das Zugriffstoken zum Erstellen eines SharePoint-Clientkontextobjekts verwendet. Mithilfe eines zwischengespeicherten Aktualisierungstokens direkt von ACS muss beim Start der Sitzung kein zusätzlicher Netzwerkaufruf an SharePoint erfolgen, sodass Benutzer, die das Add-In innerhalb der Lebensdauer des Aktualisierungstokens im Cache erneut verwenden, schneller starten können.
  • Wie im Beispiel am Ende des vorhergehenden Abschnitts kann der Code abgelaufene Token nicht verarbeiten. Nachdem das Clientkontextobjekt erstellt wurde, verwendet es das gleiche Zugriffstoken. Ein Schutz vor einem abgelaufenen Zugriffstoken besteht darin, das Zugriffstoken zusätzlich zum Aktualisierungstoken zwischenzuspeichern. Sie ändern dann den folgenden Code so, dass er die GetAccessToken-Methode nur abruft, wenn sich kein abgelaufener Zugriffstoken im Cache befindet.

    Während das Aktualisierungstoken auf dem Client zwischengespeichert werden kann, z. B. in einem Cookie, kann sich das Zugriffstoken aus Sicherheitsgründen nur in einem serverseitigen Cache befinden. Das Aktualisierungstoken ist verschlüsselt und kann nur von ACS entschlüsselt werden. Aber das Zugriffstoken ist lediglich codiert (mit Base-64-Codierung) und kann ganz einfach durch einen Man-in-the-Middle-Angriff decodiert werden.

  • Die in diesem Code referenzierte TokenCache-Klasse ist weiter unten in diesem Abschnitt definiert.

Code, der einer Default.aspx-Seite zugrunde liegt

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.Samples;
using Microsoft.SharePoint.Client;

namespace DynamicAppPermissionRequest
{
  public partial class Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      Uri sharePointSiteUrl = new Uri("https://fabrikam.sharepoint.com/print/");

      if (Request.QueryString["code"] != null)
      {
        TokenCache.UpdateCacheWithCode(Request, Response, sharePointSiteUrl);
      }

      if (!TokenCache.IsTokenInCache(Request.Cookies))
      {
        Response.Redirect(TokenHelper.GetAuthorizationUrl(sharePointSiteUrl.ToString(), "Web.Write"));
      }
      else
      {
        string refreshToken = TokenCache.GetCachedRefreshToken(Request.Cookies);
        string accessToken =
        TokenHelper.GetAccessToken(
                    refreshToken,
                    "00000003-0000-0ff1-ce00-000000000000",
                    sharePointSiteUrl.Authority,
                    TokenHelper.GetRealmFromTargetUrl(sharePointSiteUrl)).AccessToken;

        using (ClientContext context =
                TokenHelper.GetClientContextWithAccessToken(sharePointSiteUrl.ToString(),
                                                            accessToken))
        {
          context.Load(context.Web);
          context.ExecuteQuery();

          Response.Write("<p>" + context.Web.Title + "</p>");
        }
      }
    }
  }
}

Es folgt ein Codebeispiel für ein Token-Cachemodul, das der vorherige Beispielcode abruft. Als Cache werden Cookies verwendet. Es gibt andere Optionen zum Zwischenspeichern. Ausführliche Informationen finden Sie unter Handhabung von Sicherheitstoken in vom Anbieter gehosteten Add-Ins für SharePoint mit niedriger Vertrauensebene.

Codebeispiel für ein Token-Cachemodul

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.SharePoint.Samples;

namespace DynamicAppPermissionRequest
{
  public static class TokenCache
  {
    private const string REFRESH_TOKEN_COOKIE_NAME = "RefreshToken";

    public static void UpdateCacheWithCode(HttpRequest request,
                                            HttpResponse response,
                                            Uri targetUri)
    {
      string refreshToken =
          TokenHelper.GetAccessToken(
              request.QueryString["code"],
              "00000003-0000-0ff1-ce00-000000000000",
              targetUri.Authority,
              TokenHelper.GetRealmFromTargetUrl(targetUri),
              new Uri(request.Url.GetLeftPart(UriPartial.Path))
          ).RefreshToken;
      SetRefreshTokenCookie(response.Cookies, refreshToken);
      SetRefreshTokenCookie(request.Cookies, refreshToken);
    }

    internal static string GetCachedRefreshToken(HttpCookieCollection requestCookies)
    {
      return GetRefreshTokenFromCookie(requestCookies);
    }

    internal static bool IsTokenInCache(HttpCookieCollection requestCookies)
    {
      return requestCookies[REFRESH_TOKEN_COOKIE_NAME] != null;
    }

    private static string GetRefreshTokenFromCookie(HttpCookieCollection cookies)
    {
      if (cookies[REFRESH_TOKEN_COOKIE_NAME] != null)
      {
        return cookies[REFRESH_TOKEN_COOKIE_NAME].Value;
      }
      else
      {
        return null;
      }
    }

    private static void SetRefreshTokenCookie(HttpCookieCollection cookies, string refreshToken)
    {
      if (cookies[REFRESH_TOKEN_COOKIE_NAME] != null)
      {
        cookies[REFRESH_TOKEN_COOKIE_NAME].Value = refreshToken;
      }
      else
      {
        HttpCookie cookie = new HttpCookie(REFRESH_TOKEN_COOKIE_NAME, refreshToken);
        cookie.Expires = DateTime.Now.AddDays(30);
        cookies.Add(cookie);
      }
    }
  }
}

Siehe auch