Search code examples
azuresharepointsharepoint-onlineazure-ad-graph-apisharepoint-rest-api

How to Access Sharepoint Online API with v1 Azure AD Application and Client Credentials


I am unable to make an API call to Sharepoint Online using Postman. I have successfully made API calls to the Graph API so I am familiar with how I think this should work.

I have followed these instructions for setup:

The first article says that it won't accept access tokens generated using a client secret, but I have generated tokens with a secret and a certificate and have found no difference.

When calling anything, such as:

https://<tenant>.sharepoint.com/_api/web

I get the error:

{"error_description":"Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown."}

here's a sample of the access token I generate with the v1 /token endpoint:

{
  "aud": "https://microsoft.sharepoint-df.com/",
  "iss": "https://sts.windows.net/462c0b***********c3708/",
  "iat": 1569243291,
  "nbf": 1569243291,
  "exp": 1569247191,
  "aio": "42FgYDiXt***********==",
  "app_displayname": "T***********n",
  "appid": "00c***********2b",
  "appidacr": "2",
  "idp": "https://sts.windows.net/46***********708/",
  "oid": "2f8a5***********684",
  "roles": [
    "User.ReadWrite.All",
    "TermStore.Read.All",
    "Sites.FullControl.All"
  ],
  "sid": "5ab8d57***********0bc",
  "sub": "2f8a5***********684",
  "tid": "462c0***********708",
  "uti": "aHt8d***********9AA",
  "ver": "1.0"
}

Solution

  • The error message seems to imply that my resource parameter in the /token endpoint call was set incorrectly. I believe this is omitted in the Microsoft documentation, since the documentation is so divided. The correct token endpoint call for a V1 app to call SharePoint Online looks like the following:

    Web Service

    POST https://login.microsoftonline.com/<TARGET-TENANT-ID OR NAME>/oauth2/token
    

    Parameters

    client_id= <Application ID from Azure Portal>
    grant_type=client_credentials
    resource= https://<TARGET-TENANT-NAME>.sharepoint.com
    client_assertion_type= urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    client_assertion= <See Link Above to create assertion>
    

    The links above omit how to calculate the x5t value for the certificate JWT. You can use this:

    echo $(openssl x509 -in certificate.pem -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64
    

    which I got from here: How to obtain value of "x5t" using Certificate credentials for application authentication

    If you try to use client secret instead of client assertion, you'll get a token back, but the SharePoint Online REST API will return:

    Unsupported app only token.