Milind
Milind

Reputation: 1955

Calling Graphi API from Classic JavaScript through msal.js

I am trying to do silent login through msal.js and then trying to call graph api but always I get 403 error. When I decrypt my access token through jwt.ms I can see that audience is correct but scopes are showing wrong. Hope some can help me.

My code

let config = {
    auth: {
      clientId: _spPageContextInfo.spfx3rdPartyServicePrincipalId,
      authority: `https://login.microsoftonline.com/${_spPageContextInfo.aadTenantId}`,
      redirectUri: 'https://xxx.sharepoint.com/sites/xxx-Dev/Pages/myportal.aspx',
      validateAuthority: false,
      postLogoutRedirectUri: window.origin,
    },
    cache: {
      cacheLocation: 'localStorage',
      storeAuthStateInCookie: true
    }
  }

  let myMSALObj = new Msal.UserAgentApplication(config)
  let graphConfig = {
    graphGroupEndpoint: "https://graph.microsoft.com/v1.0/groups"
  }

  let request = {
    scopes: ["https://graph.microsoft.com/.default"]
  }


  myMSALObj.handleRedirectCallback(response => { console.log(response) });
  //const idTokenScope = { scopes: [_spPageContextInfo.spfx3rdPartyServicePrincipalId] }

  const handleError = (error) => {
    if (error.errorCode === 'consent_required'
      || error.errorCode === 'interaction_required'
      || error.errorCode === 'login_required') {
      //myMSALObj.loginRedirect(idTokenScope);
      myMSALObj.loginRedirect(request);
      return;
    }
    throw error;
  };

  const getToken = () => {
    const date = new Date();
    const user = myMSALObj.getAccount();
    if (!user) {
      //myMSALObj.loginRedirect(idTokenScope);
      myMSALObj.loginRedirect(request);
      return;
    }
    //myMSALObj.acquireTokenSilent(idTokenScope).then(response => {
    myMSALObj.acquireTokenSilent(request).then(response => {
      console.log(`${date.toLocaleTimeString()}`, response.accessToken);
      callMSGraph(graphConfig.graphGroupEndpoint, response.accessToken, graphAPICallback)
    }).catch(handleError);
  }
  getToken()

  function callMSGraph(theUrl, accessToken, callback) {
    var xmlHttp = new XMLHttpRequest()
    xmlHttp.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200)
        callback(JSON.parse(this.responseText))
    }
    xmlHttp.open("GET", theUrl, true)
    xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken)
    xmlHttp.send()
  }
  function graphAPICallback(data) {
    document.write(JSON.stringify(data, null, 2))
  }

My decoded token enter image description here

My app permission enter image description here

Upvotes: 0

Views: 456

Answers (1)

Jack Jia
Jack Jia

Reputation: 5549

There are two kinds of permissions: one is application permission, the othre one is delegated permission. And "https://graph.microsoft.com/.default" is for application permisisons.

enter image description here

With interactively signning from browser, you will be asked to provided with your credentials. In this way, you will get an access token for yourself, which is with delegated permissions. We call this as OAuth 2.0 authorization code flow

However, as you do not set any required delegated permission in your request scope, Azure AD just return you an access token with basic delegated permissions (openid, email an profile).


By the way, if you just want to get an access token with application permissions. You just need to use the OAuth 2.0 client credentials flow to get a token.

Upvotes: 1

Related Questions