2

I am working on a PHP web app that needs to make HTTP requests to the Sharepoint API with Sites.Selected permission to a specific SharePoint site. It is NOT viable for me to provide a user sign-in experience so I need to treat it as a non-user/daemon application.

I've read the docs and looked at many different forums for the solution but as of yet I've been unsuccessfull in obtaining a SPO specific access token, although I think I'm close.

I am using this StackOverflow answer as a guide: https://stackoverflow.com/a/63386756/19038862

This is what I've done:

  1. Registered an Azure App: (Image of my Azure App Overview)
  2. Created a client secret in the App dashboard: (Image of the client secret page)
  3. Successfully sent a request to https://login.microsoftonline.com/{{app_tenant_id}}/oauth2/v2.0/token using the client secret in Postman: (Image of Postman request)

The request made in step 3 returns an access token (I assume a MS Graph access token?), but it DOES NOT return a refresh token, which is what the afforementioned StackOverflow answer suggests you need to "swap" for an SPO specific access token.

How do I obtain this refresh token so that I can swap it for a SPO access token? Or what better way is there to get my hands on a SPO specific access token from a non-user app?

Ruan
  • 23
  • 5

3 Answers3

2

I wrote this gist to guide you into getting Sites.Selected access to the desired site: https://gist.github.com/ruanswanepoel/14fd1c97972cabf9ca3d6c0d9c5fc542

This guide shows you how to configure this as Application permissions, and via the Graph API.

I've found going through the Graph API is the best way to go.

Also strangely it's not possible to get delegated Sites.Selected permissions. You must set it up as an Application permission.

rrswa
  • 1,005
  • 1
  • 9
  • 23
0

In the guide is described that you have to get a delegated auth token from graph but you are getting an application auth token. The token response of this flow does not contain a refresh_token. See here.

But you already wrote that you are not able to provide a user sign-in experience. One workaround would be to once manually get the access_token and refresh_token of a user with the delegated flow and then periodically get a new access_token with the refresh_token on your server. You could store these values in your database and update them when you fetch a new one.

Optimal
  • 407
  • 3
  • 9
  • I see, so you are suggesting to get an `access_token` and `refresh_token` of a user (like the app admin), then use those in my code to generate a SPO token? How long do the delegated auth tokens exist? – Ruan Aug 26 '22 at 07:41
  • Yes. In the response, you get the property `expires_in`, see [here](https://learn.microsoft.com/de-de/graph/auth-v2-user). One possibility would be to create a service that runs every 30 minutes and refreshes the `access_token`. – Optimal Aug 26 '22 at 08:00
0

First, the daemon-based client credential flow does not return a refresh token for you. You also can't redeem the refresh token of the graph API for an access token for SPO, which are two completely different API resources.

To get an access token for SPO you just need to set scope to: https://{tenant-name}.sharepoint.com/.default.

halfer
  • 19,824
  • 17
  • 99
  • 186
Carl Zhao
  • 8,543
  • 2
  • 11
  • 19
  • I am getting this response from the server trying to make a request to SPO api: `Unsupported app only token.` – Ruan Aug 27 '22 at 02:17
  • This means that the SPO APIs you are calling do not support application-only tokens, and you can refer to this answer to get a user token: https://stackoverflow.com/questions/73481246/sharepoint-oauth-2-0-api-for-access-and-refresh-token/73499578#73499578 – Carl Zhao Aug 29 '22 at 02:04
  • the url for step 1 displays `AADSTS500113: No reply address is registered for the application.`. Looking at [this](https://stackoverflow.com/a/66275320/19038862) answer, what should I put as my callback url in this context (`/authorize` endpoint in browser)? – Ruan Aug 29 '22 at 07:45
  • This is the callback address after you get the authorization code, and as a test, you can set it to: `http://localhost` – Carl Zhao Aug 29 '22 at 08:50
  • Hi, would you please provide us with an update on the status of your issue? – Carl Zhao Aug 30 '22 at 09:25
  • I've not extensively looked into this yet, but when I tried I got this message `"AADSTS5001: The redirect URI 'https://localhost' specified in the request does not match the redirect URIs configured for the application..."`. I assume the `https` url is the one in the request. I did try change the callback url to `https` but that gave me an "Unable to connect" message. I also tried to make the request with `http` instead, but also no luck. – Ruan Aug 31 '22 at 03:05
  • Make sure that the redirect URI you are using matches the redirect URI that you configured in Azure AD. Refer to my previous answer: https://stackoverflow.com/questions/65824309/aadsts50011-the-reply-url-specified-in-the-request-does-not-match-the-reply-url/65824980#65824980 – Carl Zhao Aug 31 '22 at 10:11