30

Just starting to work with SharePoint and Microsoft authentication and trying to get a SharePoint List into a JavaScript App. From Microsoft documentation, I need to use the following:

GET https://{site_url}/_api/web/lists/GetByTitle('List Title')
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"

Have searched everywhere to find an definitive answer to how to obtain this accessToken. All the documentation I can find from Microsoft seem to be out of date. Does anyone know the current method to obtain an accessToken?

L H
  • 1,145
  • 3
  • 12
  • 25
  • 1
    You can have a look at the following that helped me: https://anexinet.com/blog/getting-an-access-token-for-sharepoint-online/ – Darrel K. Dec 08 '20 at 16:20

5 Answers5

31

To call SharePoint specific APIs you need to get a SPO specific access token. You can "swap" an regular MS Graph refresh token for an SPO specific token by doing the following:

  1. Get a delegated auth token from graph as you normally would (https://learn.microsoft.com/en-us/graph/auth-v2-user)
  2. Use the refresh_token you got and exchange it for an SPO access token by calling the auth endpoint again:
POST https://login.microsoftonline.com/{{tenantName}}/oauth2/v2.0/token

With the following form data:

client_id=<APP ID>
client_secret=<APP SECRET>
refresh_token=<REFRESH TOKEN FROM ABOVE>
grant_type=refresh_token
scope=https://<YOUR TENANT NAME>.sharepoint.com/Sites.Read.All
  1. Take the access token and call the SPO API

You must ensure your app is registered with the correct permissions. In the case above the app must have Sites.Read.All for example.

Chris Johnson
  • 1,230
  • 7
  • 15
  • 2
    It should be marked as Answer! Thanks, it really works. @chris-johnson, it would be nice to share the link references on the documentation about this approach. – 23W May 24 '21 at 18:36
  • 2
    @chris-johnson you are just the best. I spent whole day looking for a solution and only your answer helped me. Works like a charm! – xalien Aug 26 '21 at 14:15
  • @Chris Johnson, I'm using MSAL and I don't get a refresh token in the response in IAuthenticationResult object, but only accessToken. But with this accessToken I'm unable to access Sharepoint. Could you please help. Version : msal 2.2.3 – Rakesh Apr 07 '22 at 13:39
  • @Chris Johnson They don't expose refresh token anymore. In that case, how can we access SPO? – Rakesh Apr 07 '22 at 14:07
  • 1
    Just a note for anyone else stuck on this like me (I kept trying to use a graph token with SPO thinking that these 1, 2 points above are different possibilites). They are steps that should be followed in the order lol – Herz3h Jan 26 '23 at 09:49
8

You could refer to this article to get access token:

https://global-sharepoint.com/sharepoint-online/in-4-steps-access-sharepoint-online-data-using-postman-tool/

Post https://accounts.accesscontrol.windows.net/<Tenant ID>/tokens/OAuth/2

Body:

grant_type     client_credentials
client_id      <Client ID>
client_secret  <Client Secret>
resource       00000003-0000-0ff1-ce00-000000000000/<tenant>.sharepoint.com@<Tenant ID>

My test result:

enter image description here

Michael Han
  • 3,475
  • 1
  • 6
  • 8
  • Is there any option to change the access token's lifetime? – dk7 Mar 07 '22 at 00:25
  • I've got the access token successfully, but got the issue with request _api/web. The response - Status: 403 Forbidden. Attempted to perform an unauthorized operation. Could you advise please? – Bohdan Jul 12 '23 at 14:18
  • @Bohdan - Did you solve the 403 ? I got the same issue after using the access token – VitalyT Aug 02 '23 at 13:56
  • @VitalyT _api/web - that was incorrect URL for me, and that was the reason of 403. But the same token worked successfully for another URL: https://{Your SharePoint site URL}/sites/{Your Site Name}/_api/web – Bohdan Aug 02 '23 at 17:16
1

There is not much documentation for SP API, but it still works. You may follow documentation to get token for Graph API by whatever type of authentication is suitable for your scenario, but instead of passing scopes for Graph API (which is "https://graph.microsoft.com/.default"), you should pass scopes for Sharepoint API which is "https://{your tenant name}.sharepoint.com/.default"

".default" will provide you the access with all permissions which was assigned in Azure AD - so also make sure, that Azure admin has granted you required API permissions for SharePoint API.

This will also work for MSAL.

kadis
  • 181
  • 6
0
export const pca = new PublicClientApplication(msalConfig);
// Create an Axios instance

export const sharepointApiCall = axios.create({ baseURL: `${BASE_URL}/_api` });

// MSAL.js v2 exposes several account APIs, logic to determine which account to use is the responsibility of the developer

const account = pca.getAllAccounts()[0];

// Define your access token request configuration

const accessTokenRequest = {
  //note: leave this scopes for possible future extension - ms has no docs for the names
  // scopes: [
  //   'openid',
  //   'profile',
  //   'email',
  //   'allsites.fullcontrol',
  //   'allsites.manage',
  //   'allsites.read',
  //   'allsites.write',
  //   'sites.fullcontrol.all',
  //   'sites.manage.all',
  //   'sites.read.all',
  //   'sites.readwrite.all',
  //   'user.read',
  //   'user.read.all',
  // ],
  scopes: [`${tenantName}/.default`],



 // other token request options
  account,
  redirectUri: 'http://localhost:3001',
};

// Add an Axios interceptor

sharepointApiCall.interceptors.request.use(async (config) => {
  try {
    const accessTokenResponse = await pca.acquireTokenSilent(accessTokenRequest);
    const accessToken = accessTokenResponse.accessToken;

// Add the token to the request headers
config.headers['Authorization'] = `Bearer ${accessToken}`;
    return config;
  } catch (error) {
    console.error('Error acquiring token:', error);
    return Promise.reject(error);
  }

});

that scopes: [tenant] is the @kadis solution which works,

token is refreshed and cashed automatically so there is no need to have fancy intercepting - but with this you can more easily call rest API of sharepoint for example with react query and if the error occurs use useMsal to login/logout

hope that helps to anyone in future

0

If you just need to log in with username/password and call REST API, for example, to download a file, these are the steps you need to do..

You can ask directly for scope to access your SharePoint, no need to use refresh token to get new access token, as described in the first answer - thank God, for that answer.

curl --location --request GET 'https://login.microsoftonline.com/[TENANT ID]/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=[AAD APPLICATION CLIENT ID]' \
--data-urlencode 'scope=https://[YOUR DOMAIN].sharepoint.com/Sites.Read.All' \
--data-urlencode 'username=[USER THAT HAS ACCESS TO THE SITE]' \
--data-urlencode 'password=[PASSWORD OF THAT USER]' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_secret=[AAD APPLICATION CLIENT SECRET]'


curl --location 'https://[YOUR DOMAIN].sharepoint.com/sites/_api/web/lists/GetByTitle('\''Documents'\'')/files' \
--header 'Authorization: Bearer [ACCESS TOKEN FROM PREVIOUS STEP]'

Remember to add Graph API permission Sites.Read.All to the AAD application. There is also SharePoint permission AllSites.Read, not sure if they are the same thing but I use the first one.