Laden...

Per OAuth2 an Sharepoint Online via REST --> Unsupported app only token

Erstellt von GambaJo vor einem Jahr Letzter Beitrag vor einem Jahr 1.180 Views
GambaJo Themenstarter:in
105 Beiträge seit 2006
vor einem Jahr
Per OAuth2 an Sharepoint Online via REST --> Unsupported app only token

Ich habe schon so einige Tutorials ausprobiert, aber nichts hat funktioniert.
Ich versuche mich per OAuth2 und REST an Sharepoint zu authentifizieren.

POST "https://login.microsoftonline.com/{targetSharepointApi.TenantID}/oauth2/token"

FormUrlEncodedContent:
client_id=myId&
client_secret=mySecret&
grant_type=client_credentials&
resource=https://myTenant.sharepoint.com

(habe es auch noch zusätzlich mit scope=https://myTenant.sharepoint.com/.default versucht).

Bekomme daraus ein JSON-Objekt in dem unter anderem auch ein accessToken enthalten ist. So weit, so gut.
Versuche ich dann aber irgendwelche Ressourcen aufzurufen (Authorization=Bearer {accessToken}), bekomme ich ein 401 zurück mit der Meldung "Unsupported app only token".
Ich habe das Gefühl, da fehlt noch ein Schritt.

App ist im Azure-Portal angelegt, Secret ist angelegt und die App hat (erst mal) weitreichende Berechtigungen.
Kann mir bitte jemand auf die Sprünge helfen?

16.807 Beiträge seit 2008
vor einem Jahr

SharePoint verwendet die Microsoft Identity Platform.
Du kannst daher jedes Tutorial nehmen, das das Setup von Microsoft Identity Platform verwendet.

Ebenso kannst Du einfach das Microsoft Identity SDK verwenden.

Was Du mit den Code-Schnippseln hier willst: keine Ahnung.
Aus dem Zusammenhang gerissen und einfach mal gepostet? Ja, dann kommt invalid Token bei raus 🙂

https://login.microsoftonline.com/{targetSharepointApi.TenantID}/oauth2/token ist ein uralter Endpunkt.
Jede aktuelle Doku von MS zeigt den aktuellen Endpunkt
https://login.microsoftonline.com/<tenant>/v2.0/oauth2/token

Je nachdem was Du machst, kann es auch sein, dass Du aufgrund der Sicherheitsleveln (zB Full Access) den Weg über ein Zertifikat gehen musst.
Dafür spricht zumindest die Fehlermeldung (direkte Einstiegtsdoc von SharePoint)
Granting access via Azure AD App-Only

GambaJo Themenstarter:in
105 Beiträge seit 2006
vor einem Jahr

Bitte entschuldige meine Unwissenheit.

Was Du mit den Code-Schnippseln hier willst: keine Ahnung.
Aus dem Zusammenhang gerissen und einfach mal gepostet? Ja, dann kommt invalid Token bei raus 🙂

Ich kenne das so, dass man bei einer Frage in einem Forum erst mal das Problem beschreibt und was man bereits gemacht/ausprobiert hat.
Ich habe viele Tutorials ausprobiert wie das hier und ähnliche. Je nach Tutorial war mal die neue und mal die alte URL, wobei ich nicht erkennen konnte, welche davon die Aktuelle ist. So oder so, ich bekomme bei beiden URLs das gleiche Ergebnis.

Meine Code-Schnippsel sehen so aus, wie in dem Tutorial weiter oben. HTTP-Aktion + URL + Header. Kann ja sein, dass eines davon falsch ist.

Ebenso kannst Du einfach das Microsoft Identity SDK verwenden.

Am liebsten würde ich tatsächlich plain REST verwenden. Ich habe mit den Microsoft-SDKs schlechte Erfahrung gemacht. Eine davon war ein ASP.NET Core-Library. Sie versuchte auf die Registry zu zugreifen. Da mein Service unter Ubuntu gehostet wird, gab's die natürlich nicht. Solche "Überraschungen" möchte ich gerne vermeiden.

Je nachdem was Du machst, kann es auch sein, dass Du aufgrund der Sicherheitsleveln (zB Full Access) den Weg über ein Zertifikat gehen musst.

Hmm, das wäre schlecht. Mein Service ist eine Middleware, die meist on-prem läuft. Sie bietet eine REST-API über die man z.B. Bibliothekseinträge und die dazugehörigen Dateien anfordern kann.

Bisher lief das so:
Ein Client sendet einen HTTP-Request zu meiner Middleware. In diesem Request ist unter anderem die URL zum Sharepoint-Tenant (z.B. https://myTenant.sharepoint.com), Sharepoint Benutzer Credentials (Benutzername und Passwort) und die ID einer Bibliothek/Liste. Die Middleware hat dann mit den Credentials einen Cookie angefordert und dann diese Anfrage inkl. Cookie dann an Sharepoint weiter geleitet, eine Antwort von Sharepoint bekommen und diese Antwort dann aufgearbeitet an den Client weiter geleitet. Das funktioniert auch wunderbar.

So soll es in Zukunft laufen:
Die Funktionalität von oben soll erhalten bleiben. Lediglich die Art der Authentifizierung soll von Basic auf OAuth2 umgestellt werden. Da es sich um einen Dienst, der auf irgendeinem Server läuft, handelt, darf nicht der Dialog mit der Anforderung der Zugriffsrechte erscheinen. Das muss vorher korrekt im Azure-Portal konfiguriert sein. Auch hier bin ich mir unsicher.
Sollte ein Zertifikat notwendig sein, müsste der Client dieses bei jedem Request mit senden. Das würde ich auch gerne vermeiden.

Die Aktionen, die meine Middleware auf Sharepoint durchführt:

  • Lesen der Schemata von Listen/Bibilotheken
  • Lesen der Schemata von Content-Types
  • CRUD-Operationen auf Bibliothekseinträge
  • Hoch- und Runterladen von Dateien in/aus diesen Bibliothekseinträgen

Mir ist jetzt auch noch was anderes aufgefallen.
Wenn ich den bisherigen Weg gegangen bin (mit den Credentials), habe ich folgende URL aufgerufen um eine Bibliothek zu holen:

https://myTenant.sharepoint.com/_api/web/lists(guid'{listId}')

Kann ich das so weiter nutzen, oder muss ich jetzt die Graph-API verwenden?

https://graph.microsoft.com/sites/{siteId}/lists/{listId}

Ich habe das jetzt mal mit der Graph SDK und diesem Beispiel-Code (etwas erweitert um das Holen der Spalten einer Liste) erfolgreich ausprobiert. Aber das JSON-Objekt hat eine andere Struktur, als bei meinem bisherigen Weg mit Credentials. Kann man OAuth2 nur mit der Graph-API verwenden, oder geht das auch über die bisherige Sharepoint REST API?

16.807 Beiträge seit 2008
vor einem Jahr

Meine Code-Schnippsel sehen so aus, wie in dem Tutorial weiter oben. HTTP-Aktion + URL + Header. Kann ja sein, dass eines davon falsch ist.

Du hast kein Code Schnipsel gepostet, sondern einfach nur eine URL und eine HTTP Methode und gesagt: "so mach ich das".
Wir können uns nun aus dem Daumen ziehen, was Du damit meinst und wie wohl Dein Code aussieht.
Jetzt wissen wir, dass wir die Parameter vergleichen sollten.... well.
Nimm doch einfach die Lib? Aber:

Eine davon war ein ASP.NET Core-Library. Sie versuchte auf die Registry zu zugreifen. Da mein Service unter Ubuntu gehostet wird, gab's die natürlich nicht.

Du hast ne Microsoft ASP.NET Core Lib verwendet, die für Mulit Platform gedacht ist und auf die Windows Registry zugreift?
Bezweifle ich.

Und wenn: wegen nem Bug, der vielleicht mal irgendwann existiert ist, willste ab sofort keine anderen Libs mehr verwenden, sondern alles selbst umsetzen?
Also statt dem Use Case umzusetzen auch alles zur Infrastruktur selbst machen?
Grandios!

Ironie und Gags bei Seite: die Auth Libs sind keine Hobby Projekte. Da arbeiten >50 Personen Vollzeit dran. Die Sicherheit und den Umfang programmierst Du nicht einfach so mal kurz nach.

Am liebsten würde ich tatsächlich plain REST verwenden.

Ganz lapidar ausgedrückt: richtig dumme Idee => Not-invented-here-Syndrom
Vor allem bei Security-Aspekten ist das eine richtig richtig schlechte Idee.

Kann ich das so weiter nutzen, oder muss ich jetzt die Graph-API verwenden?

https://graph.microsoft.com/sites/{siteId}/lists/{listId}  

Jo, steht auch in den Docs, dass die Zukunft die Graph API ist. Aber wie immer bei einer noch wachsenden API vermutlich:

  • Nicht alles ist in Graph heute verfügbar
  • Einiges gibts nur über den Graph
  • Einiges gibts (noch) nur über die alte API.
    Aber: Graph hat von Anfang an einen hohen Sicherheitsstandard bei gewissen Aktionen, die auf Zertifikaten basiert.
    Der Graph ist halt auch seit 100 Jahren im Beta Zustand.. ist halt so 🙂

Die verschiedenen Authentifizierungs- und Authorisierungszenarien, und wann man welchen Weg geht, steht in den Graph Docs: Microsoft Graph auth overview
Gleiches gilt für andere APIs mit hohen Zugriffsleveln, wie zB. Microsoft 365 API oder Security APIs.

GambaJo Themenstarter:in
105 Beiträge seit 2006
vor einem Jahr

Das mag für dich alles ironisch und witzig sein, für mich ist es das nicht.
In der Regel bekomme ich eine Anforderung zur Umsetzung und schaue dann, wie und mit was man das am besten umsetzen könnte. Ich kenne nicht jede MS-API, nicht jede Doku, nicht jede Library und nicht alle best practices, schon gar nicht im Detail. Die Entwicklung ist mittlerweile so schnell, dass ich nicht mehr hinterher komme. Ich habe den Überblick verloren. Ich kann mich mit den Dingen erst dann beschäftigen, wenn ich sie auch aktiv nutzen will/muss. Und das dauert. Irgendwann hat man sich durch Erfahrung irgendwo eingearbeitet, und dann ist es ruckzuck obsolet und durch x andere Dinge ersetzt. Ja, das ist in der IT so. Aber ich bin nun mal nur ein Mensch und habe nur begrenzte Zeit.

Ja, ich habe mich anfangs recht knapp gehalten. Einfach aus dem Grund, weil nach meiner Erfahrung lange ausführliche Beschreibungen nicht gelesen werden. #TLTR oder #TLDR.

Du hast ne Microsoft ASP.NET Core Lib verwendet, die für Mulit Platform gedacht ist und auf die Windows Registry zugreift?
Bezweifle ich.

Auch hier wusste ich nicht, dass es eine Mulit Platform Kennzeichnung gibt. ASP.NET Core ist ein plattformübergreifendes Framework. Daher habe ich naiv gedacht, auch die Librarys für ASP.NET Core wären plattformübergreifend. Vor allem wenn sie von MS kommen.
Während der Entwicklung ist nichts aufgefallen, weil ich unter Windows entwickle. Sobald mein Service dann in einem Docker-Container lief, hat es geknallt. Seit dem wäge ich genau ab, ob es mir das Risiko wert ist. Ich nutze ja selten die komplette Funktionalität einer Library.

Sei's drum, ich glaube unsere Gags und Grundsatzdiskussionen sind ein anderes Thema. Danke für deine Hilfe.