pnp / pnpjs

Fluent JavaScript API for SharePoint and Microsoft Graph REST APIs
https://pnp.github.io/pnpjs/
Other
753 stars 305 forks source link

Angular SPA authorization issue using @pnp/msaljsclient #1407

Closed rupoase closed 4 years ago

rupoase commented 4 years ago

Category

Version

Please specify what version of the library you are using: [ 2.0.10 ]

Please specify what version(s) of SharePoint you are targeting: [ Sharepoint Online ]

Expected / Desired Behavior / Question

Currently I'm developing a SPA in Angular 10 that will be packaged into a Sharepoint Add-in and installed on the Sharepoint Online tenant via AppCatalog. The SPA calls the same tenant's API endpoints to get Lists, Folders, Upload docs, etc.

I've registered the Application in the Azure Portal, added permissions, set consent scopes, etc. I've setup the MSAL pretty much according to the docs that you provided (@pnp/msaljsclient@2.0.10), the login works (pop-up opens, accepts the inputs, closes), but the '_api/... requests fail with 401 Unauthorized. On the request I see that the Bearer token is set in the header, however the api enpoint responds with {"error_description":"Invalid issuer or signature."}.

I'm expecting that the authentication, token aqcuiring and authorization to be automatically done by the library, therefore I don't have any login / logout procedure, nor found anywhere in the docs or the internet how they are done.

Looking at the documentation regarding the MSAL, which is quite light, this is what I come up with:

In sp.service.ts:

sp.setup({
  sp: {
    fetchClientFactory: MsalClientSetup({
      auth: {
        authority: environment.msal.authority,
        clientId: environment.msal.clientId,
        redirectUri: environment.msal.redirectUri
      },
      cache: {
        cacheLocation: "sessionStorage",
      },
    },
      scopes)
  }
});

Calls to the api endpoints look like these:

async getClients() {
    return await web.lists.getByTitle('clients')
      .items
      .select('Title,GUID,Status,SiteUrl,Created,Modified')
      .get();
  }

Other methods create a sub web because the subweb is not very well explained in the docs (how to get to a sub-web from the root site)

async getClientAudits(client) {
    let clientWeb = Web(`${environment.web}/${client}`);
    return await clientWeb.lists.getByTitle('Audits')
      .items
      .select('Title,GUID,TipAudit,Created,Modified')
      .get();
  }

What am I missing? What am I doing wrong? Thank you for taking your time to answer these questions.

rupoase commented 4 years ago

So, over the night I finally managed to make it work. The issue was that, by default, Azure AD includes Microsoft Graph Permissions when you set API permissions on your app. And I included every API permission into my scopes array.

github-actions[bot] commented 3 years ago

This issue is locked for inactivity or age. If you have a related issue please open a new issue and reference this one. Closed issues are not tracked.