Sp-dev-docs: Calling the API from Javascript

Created on 10 May 2018  Â·  4Comments  Â·  Source: SharePoint/sp-dev-docs

I want to call the ALM REST API from Javascript from a site outside of Office365, but I have issues obtaining a valid token.
The following error is returned when calling the ALM REST API with the token:
Error description: Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown.
x-ms-diagnostics header: 3000003;reason="Invalid audience Uri .";category="invalid_client"

In the JWT the audience value is my Application ID from Azure AD

I created an Azure AD app (Web app / API) which is registered in my tenant and I use adal-angular to get an access token.

The Azure AD app has the following permissions:
Office 365 SharePoint Online:
Read and write items and lists in all site collections
Windows Azure Active Directory:
Sign in and read user profile,
Access the directory as the signed-in user
New permissions were added, even some that require admin consent, but nothing changed, and no other permission prompts were issued.

This is the config used for ADAL:
{
instance: "https://login.microsoftonline.com/",
tenant: ",
clientId: ,
postLogoutRedirectUri: window.location.origin,
redirectUri: "http://127.0.0.1:8080/",
cacheLocation: "localStorage"
}

The ADAL acquireToken method receives the client ID (my Application ID from Azure AD) as the "resource" parameter. Passing it any kind URL from the tenant as the "resource" parameter results in a timeout error and no token is returned.

Calling the API works when using cookies instead of the Bearer access token, but this is not helpful in our use case.

I have no idea what I'm doing wrong here. Does this API need some kind of special permissions in order to work?
I couldn't find any examples online on how to call this REST API from start to finish.

Thank you!


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

docs question

All 4 comments

I managed to make this work.

I eventually found the AAD permission which is required to be able to call the ALM APIs:
Office 365 SharePoint Online > Delegated Permissions > Have full control of all site collections (this is mandatory)
Windows Azure Active Directory > Delegated Permissions > Access the directory as the signed-in user (not sure if this one is mandatory)

Another issue that I had was that permissions would not automatically update for the app in AAD enterprise applications when you change them in the app from AAD app registrations. Moreover, I wouldn't get a new consent screen where I could approve the new permissions. I had to delete the app from enterprise applications and then give it consent again in order to update the permissions.

After you select the appropriate permissions, the ADAL token and the App Only Token (the one with the self signed certificate) work fine.

About to adding the app to the app catalog: In the documentation it only says "byte array of the file". It was not clear enough, but I eventually found out it's an ArrayBuffer. What I did was I have fetched the sppkg file and then added it to the payload of the ALM API /Add call as an array buffer.

I believe that at least some of this information should have been included in the documentation, as it would have saved me and my team a lot of time.

Very useful info @calin1611 thanks for sharing.
About AAD and Consent, I think this is expected when working with ADAL and Azure V1 Endpoint. Dynamic consent (the behavior that you were expecting) is only available for v2 endpoint (https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare#incremental-and-dynamic-consent)

Also, maybe you could share the code to POST the ArrayBuffer, as seems not that obvious.
Thanks!
Also,

@luismanez I think you are right about that AAD stuff. I mentioned this so others won't have the same problems as I had.

This app was just a proof of concept and the result will later be included in the main project. The API was not called from a SP app. It was a barebones web application running locally on my computer. The goal was to install 2 SPFX apps. I served the two sppkg files along with the javascript files. For this I used Node and the http-server NPM package.

I also observed that it didn't matter if I would send the X-RequestDigest header. I never sent it and everything worked fine.

Here is the code for adding the app to the app catalog. I can confirm that it worked to add the apps to both the tenant and site collection app catalog.

    var addApp = (appPackageName) => {
      fetch(`/${appPackageName}`).then(f => f.arrayBuffer())
        .then(buffer => {
          Axios({
            url: `${this.state.siteCollectionURL}/_api/web/${this.state.appCatalogLocation}/Add(overwrite=true, url='${appPackageName}')`,
            method: 'post',
            headers: {
              'Authorization': `Bearer ${this.state.token}`,
              'Accept': 'application/json;odata=nometadata',
              'binaryStringRequestBody': true
            },
            data: buffer
          })
            .then(response => {
              console.log('[addApp] response:', response);

              // I now call the method to deploy the app and then, after it's deployed, the method to install the app
              this.deployApp(response.data.UniqueId)
            })
            .catch(err => console.log('[addApp]', err));
        });
    }

Explanation for state variables:
siteCollectionURL - The URL of the site collection where I want to install the SPFX apps
appCatalogLocation - tenantappcatalog OR sitecollectionappcatalog
token - the access token obtained from ADAL.js

I hope you find this useful.

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ken-harris picture ken-harris  Â·  3Comments

waldekmastykarz picture waldekmastykarz  Â·  3Comments

StfBauer picture StfBauer  Â·  3Comments

Ralms picture Ralms  Â·  3Comments

byrongits picture byrongits  Â·  3Comments