msal acquireTokenSilent fails with Silent authentication was denied

Viewed 8214

I'm using msal-angular and I cant use MsalInterceptor since it handles each and every request while I would like it to handle only graph requests. Therefore I'm trying to acquire a token by myself in my application.

I'm doing this like this: configuration of MsalModule

MsalModule.forRoot({
  auth: {
    clientId: 'xxxxxx',
    authority: 'https://login.microsoftonline.com/common',
    redirectUri: 'my_url',
  },
  cache: {
    cacheLocation: 'localStorage',
    storeAuthStateInCookie: false, // set to true for IE 11
  },
},
  {
    popUp: true,
    consentScopes:[
      'user.read',
      "calendars.read",
      "calendars.read.shared",
      "calendars.readwrite",
      "group.read.all",
      "openid",
      "profile"
    ],
  }),

I'm doing a login like this:

this.msalService.loginPopup({scopes: [
  'user.read',
  "calendars.read",
  "calendars.read.shared",
  "calendars.readwrite",
  "group.read.all",
  "openid",
  "profile"
]})

I'm intercepting the login succes like this

this.broadcastService.subscribe('msal:loginSuccess' ...

and I'm trying to get a token like this

const result: AuthResponse = await this.msalService.acquireTokenSilent({scopes: [
  'user.read',
  "calendars.read",
  "calendars.read.shared",
  "calendars.readwrite",
  "group.read.all",
  "openid",
  "profile"
]}).catch((error) => {
  console.log(error);
});

and I'm still getting this error: Silent authentication was denied. The user must first sign in and if needed grant the client application access to the scope 'user.read calendars.read calendars.read.shared calendars.readwrite group.read.all openid profile'.

here is my app configuration on Azure portal

enter image description here

I really don't understand where does the problem come from.

Thanks for your help

[EDIT] I've been able to get an access token by calling acquireTokenPopup when acquireTokenSilent fails like this

const result: AuthResponse = await this.msalService.acquireTokenSilent({
  scopes: [
    'user.read',
    "calendars.read",
    "calendars.read.shared",
    "calendars.readwrite",
    "group.read.all",
    "openid",
    "profile"
  ]
}).catch((error) => {
  if (error.name === "InteractionRequiredAuthError") {
    return this.msalService.acquireTokenPopup({
      scopes: [
        'user.read',
        "calendars.read",
        "calendars.read.shared",
        "calendars.readwrite",
        "group.read.all",
        "openid",
        "profile"
      ]
    })
  }
});

return result.accessToken;

}

It works but keeps flasing a popup. Could someone explain me the reason ?

Thank you

2 Answers

You must enforce the consent popup to show up. Try this

this.msalService.loginPopup({ prompt: 'consent'});

I have the similar problem and just use following code to get the exception.

   this.broadcastService.subscribe('msal:acquireTokenFailure', (payload) => {
                    console.log(payload);    
                });

InteractionRequiredAuthError: Silent authentication was denied. The user must first sign in and if needed grant the client application access to the scope 'api://1cfd57f1-ad48-4396-b95c-7fa782a178b6/access_as_user openid profile'.

In the document, it says:

InteractionRequiredAuthError: Error class, extends ServerError to represent server errors, which require an interactive call. This error is thrown by acquireTokenSilent if the user is required to interact with the server to provide credentials or consent for authentication/authorization. Error codes include "interaction_required", "login_required", and "consent_required"

For error handling in authentication flows with redirect methods (loginRedirect, acquireTokenRedirect), you'll need to register the callback.

https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-handling-exceptions?tabs=javascript

So I add "this.msalService.loginRedirect()" to the callback method to solve my problem. I also not quite understand, why should grant the permission again, but when man check the implementation of "MsalGuard" (https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/src/msal-guard.service.ts), it executes the same code "loginRedirect", if the exception is thrown by acquiring token.

By the way, I have also added Client Application ID to my API "Expose an API" in to authorize the client without to be asked to consent. The exception is fixed in my app finally.

enter image description here

Related