1

I am developing a rather simple application that retrieves files from SharePoint using the REST Office 365 API. This is a batch job running in the background with no user interface so the following simple 2-step flow is what I'm doing:

(1) Requesting an Access Token from Azure AD (supplying client ID, client secret, resource, and grant_type=client_credentials)

(2) Invoke the SharePoint API (https://{base url}/_api/v1.0/Files) using the "Authorization: Bearer " as a request header .

That process seems pretty straightforward and sounds simple but I keep getting the following error:

401 Unauthorized x-ms-diagnostics: 3001000;reason="There has been an error authenticating the request.";category="invalid_client" 

Any idea what the problem is and how this can be resolved ? I have been stuck on this for days now. I would REALLY appreciate somebody's help with this. Thanks.

0

2 Answers 2

3

SharePoint Online doesn't yet support clients accessing it using app-only tokens (resulting from client credential OAuth2 flow). It only supports delegated token aka user+app tokens (resulting from authorization code OAuth2 flow).

So, if you wish to write a client application (web app or native client app) that accesses SharePoint online - it can only be on behalf of a user, and it must involve interactive authentication of the user - after the user authenticates - they will be shown a consent page where they need to consent to your application accessing the O365 API on their behalf.

Only Mail/Calendar/Contacts APIs (Exchange Online) support clients accessing them using app-only tokens - and they have turned on this support very recently. Read about client credential flow tokens with Exchange Online APIs here: http://blogs.technet.com/b/ad/archive/2015/02/04/using-azure-ad-to-build-daemon-applications-that-call-office-365-apis.aspx, http://blogs.msdn.com/b/exchangedev/archive/2015/01/22/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx

Hope this helps.

ps: OAuth2 client credential flow doesn't issue a refresh token

Sign up to request clarification or add additional context in comments.

Comments

2

You will need an access token for the specific resource you are trying to access - in this case your sharepoint site for the Office365 REST Apis.

A good read on this can be found here: https://msdn.microsoft.com/en-us/library/azure/dn645538.aspx

Assuming your {base_url} is a sharepoint site, i.e., 'https://[site_name]-my.sharepoint.com

You can either:

(1) Initially get the access and refresh tokens using your client credentials plus a resource = {base url}

or

(2) Once you have the access and refresh token from the Azure AD resource, make a refresh_token call using:

  • client_id
  • client_secret
  • grant_type = 'refresh_token'
  • resource = {base_url}
  • refresh_token = [refresh token received from Azure AD generate token response]

In this case you'll have 2 access tokens:

  1. one that can be used for Azure AD requests
  2. one that can be used for Office365 REST Api requests.

We could not/have not found a way to have a single access token be 'valid' for more than 1 resource.

Hope this helps!

7 Comments

Here is the problem that I'm having. I use "approach #1 above" and supply client_id, client_secret, grant_type="client_credentials", and resource={base_url} and receive a response that contains an "access_token" but does NOT contain a refresh_token. When I try to use that access_token to retrieve content from {base_url} with the "Authentication: Bearer <access_token>" response header, I get no that "invalid_client" error referenced above. I am using the msdn.microsoft.com/en-us/library/azure/dn645543.aspx approach to receive an access token and that token fails when I try 2 get SP data
I can't use Approach #2 because I never get a refresh_token using the method as described here ... msdn.microsoft.com/en-us/library/azure/dn645543.aspx
I use grant_type="authorization_code". Give that a try.
Also, I used their authentication 'sandbox' to get a handle on the whole process, as it shows all the params needed for each step of the authentication and authorization process. Here's a link to the sandbox: oauthplay.azurewebsites.net
If I use grant_type="authorization_code" instead of "client_credentials" and leave the client_id, client_secret, and resource as before I get the error: "The request body must contain the following parameter: 'code'." . I don't have a code so no idea what that value is supposed to be. I've been trying to resolve this all week. There is DEFINITELY a gap there between the documentation and the way things REALLY work. I really really NEED to get this figured out. I presume it's something small but I can't find any documentation to give me the answer.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.