Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AcquireTokenSilent not working as expeced #7196

Closed
2 tasks
renu10-dot opened this issue Jul 11, 2024 · 5 comments
Closed
2 tasks

AcquireTokenSilent not working as expeced #7196

renu10-dot opened this issue Jul 11, 2024 · 5 comments
Labels
bug-unconfirmed A reported bug that needs to be investigated and confirmed msal-angular Related to @azure/msal-angular package msal-browser Related to msal-browser package Needs: Author Feedback Awaiting response from issue author no-issue-activity Issue author has not responded in 5 days public-client Issues regarding PublicClientApplications question Customer is asking for a clarification, use case or information.

Comments

@renu10-dot
Copy link

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

2.22.0

Wrapper Library

MSAL Angular (@azure/msal-angular)

Wrapper Library Version

2.1.1

Public or Confidential Client?

Public

Description

We were using msal 1.1.2 version initially in my application but as we migrated to angular14 we migrated msal v1 to msal v2. I can see previously msal was saving msal.idtoken, authority in session storage but in v2 it is not saved msal.idtoken in session storage.
So I explicitly saving token in session so I can read it in interceptor and send in header for http calls. We are calling acquireTokenSilent() after 50 mins ,10 mins before token gets expired. I am getting error "InteractionRequiredAuthError: invalid_grant: AADSTS65001: The user or administrator has not consented to use the application with ID " When we were using msal v1 idtoken was getting saved in session as per screenshot2.

Error Message

image MsalSession

MSAL Logs

No response

Network Trace (Preferrably Fiddler)

  • Sent
  • Pending

MSAL Configuration

const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1; // Remove this line to use Angular Universal

export function loggerCallback(logLevel: LogLevel, message: string) {
  console.log(message);
}

export function MSALInstanceFactory(): IPublicClientApplication {
  return new PublicClientApplication({
    auth: {
      clientId:environment.clientId, //'bdecb075-4d5d-4de4-8006-7e5a23c5568d',
      redirectUri: environment.clientUrlDomain,//'http://localhost:4200',
      authority: environment.authority,
      navigateToLoginRequestUrl: false,//'https://login.microsoftonline.com/4cc65fd6-9c76-4871-a542-eb12a5a7800c'
      postLogoutRedirectUri:environment.clientUrlDomain
    },
    cache: {
      cacheLocation: BrowserCacheLocation.SessionStorage,
      storeAuthStateInCookie: isIE, // set to true for IE 11. Remove this line to use Angular Universal
    },
    system: {
      loggerOptions: {
        loggerCallback,
        logLevel: LogLevel.Info,
        piiLoggingEnabled: false
      }
    }
  });
}

export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
  const protectedResourceMap = new Map<string, Array<string>>();
  protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read'],);
  protectedResourceMap.set('/client/api/user/*', [ "scope-for-this-api"]);
  // protectedResourceMap.set('https://graph.microsoft-ppe.com/v1.0/me', ['user.read']); // PPE testing environment

  return {
    interactionType: InteractionType.Redirect,
    protectedResourceMap
  };
}

export function MSALGuardConfigFactory(): MsalGuardConfiguration {
  return {
    interactionType: InteractionType.Redirect,
    authRequest: {
      scopes: ['user.read',"openid","profile"]
    },
  };
}

Relevant Code Snippets

app.module.ts 
Providers added
 providers:  [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    },
    {
      provide: MSAL_INSTANCE,
      useFactory: MSALInstanceFactory
    },
    {
      provide: MSAL_GUARD_CONFIG,
      useFactory: MSALGuardConfigFactory
    },
    {
      provide: MSAL_INTERCEPTOR_CONFIG,
      useFactory: MSALInterceptorConfigFactory
    },
    MsalService,
    MsalGuard,
    MsalBroadcastService
  ],
  bootstrap: [AppComponent,MsalRedirectComponent]

app.component.ts

 constructor(
    @Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration,
    private authService: MsalService,
    private msalBroadcastService: MsalBroadcastService,	private storageService: StorageService,
    private authenticationService:AuthenticationService
  ) {}

  ngOnInit(): void {
    this.isIframe = window !== window.parent && !window.opener; // Remove this line to use Angular Universal
    this.setLoginDisplay();


    this.authService.instance.enableAccountStorageEvents(); // Optional - This will enable ACCOUNT_ADDED and ACCOUNT_REMOVED events emitted when a user logs in or out of another tab or window
    this.msalBroadcastService.msalSubject$
      .pipe(
        filter((msg: EventMessage) => msg.eventType === EventType.ACCOUNT_ADDED || msg.eventType === EventType.ACCOUNT_REMOVED),
      )
      .subscribe((result: EventMessage) => {
        console.log("Result:-----",result);
        if (this.authService.instance.getAllAccounts().length === 0) {
          window.location.pathname = "/";
        } else {
          this.setLoginDisplay();
        }
      });
      this.msalBroadcastService.msalSubject$
   .pipe(
      filter(
         (msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS 
         || msg.eventType === EventType.SSO_SILENT_SUCCESS)
       ).subscribe((result: EventMessage) => {
          const payload = result.payload as AuthenticationResult;
			sessionStorage.setItem('exp', payload.expiresOn.getTime().toString());
			setTimeout(() => {
				this.setLoginDisplay();
				this.authenticationService.startTimer(this.authenticationService.getTokenTimeout())
			}, 500)
          console.log("Payload:-",payload);
    });
    
    this.msalBroadcastService.inProgress$
      .pipe(
        filter((status: InteractionStatus) => status === InteractionStatus.None),
        takeUntil(this._destroying$)
      )
      .subscribe(() => {
        this.checkAndSetActiveAccount();
        this.setLoginDisplay();
        if(!this.loginDisplay)
          {
            this.authenticationService.logIn();
          }

      })
  }

  setLoginDisplay() {
    this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
    if(this.loginDisplay)
      {
    const userName = this.authService.instance.getAllAccounts()[0].name;
		const userEmail = this.authService.instance.getAllAccounts()[0].username;
	  const exp = this.authService.instance.getAllAccounts()[0].idTokenClaims.exp;
    console.log("Account:-",this.authService.instance.getAllAccounts()[0]);
		console.log("User Name:-",userName);
		console.log("User Email:-",userEmail);
		console.log("exp:-",exp);
    console.log("Token:-",this.authService.instance.getAllAccounts()[0].idToken);

		this.storageService.userName = userName
		this.storageService.userEmail = userEmail;
		this.storageService.tokenExp = +exp;
    this.storageService.msalToken = this.authService.instance.getAllAccounts()[0].idToken;
    this.authenticationService.loggedInSrc.next(true);
      }
  }

  checkAndSetActiveAccount(){
    /**
     * If no active account set but there are accounts signed in, sets first account to active account
     * To use active account set here, subscribe to inProgress$ first in your component
     * Note: Basic usage demonstrated. Your app may require more complicated account selection logic
     */
    let activeAccount = this.authService.instance.getActiveAccount();
    if (!activeAccount && this.authService.instance.getAllAccounts().length > 0) {
      let accounts = this.authService.instance.getAllAccounts();
      this.authService.instance.setActiveAccount(accounts[0]);
    }
  }

 
  ngOnDestroy(): void {
    this._destroying$.next(undefined);
    this._destroying$.complete();
  }
authentication.service.ts

public logIn() {
		console.log("Trying MS login");
		if(this.msalGuardConfig.authRequest)
			{
			  this.msalService.loginRedirect({...this.msalGuardConfig.authRequest} as RedirectRequest)
			}
			else
			{
			  this.msalService.loginRedirect();
			}
	}

public LoginSilent() {
		console.log("Login Silent called");
		this.removeOldToken();
		const scope = {
			scopes: [
				enviornment.clientid
				
			],
		}
		this.msalService.instance.acquireTokenSilent(scope);

Reproduction Steps

with the help of code provided above you can reproduce the issue.

Expected Behavior

on AcquireTokenSilent token should be refreshed silently without redirecting user to login .

Identity Provider

Entra ID (formerly Azure AD) / MSA

Browsers Affected (Select all that apply)

Edge

Regression

No response

Source

Internal (Microsoft)

@renu10-dot renu10-dot added bug-unconfirmed A reported bug that needs to be investigated and confirmed question Customer is asking for a clarification, use case or information. labels Jul 11, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: Attention 👋 Awaiting response from the MSAL.js team label Jul 11, 2024
@github-actions github-actions bot added msal-angular Related to @azure/msal-angular package msal-browser Related to msal-browser package public-client Issues regarding PublicClientApplications labels Jul 11, 2024
@tnorling
Copy link
Collaborator

tnorling commented Jul 15, 2024

Does it work after redirecting to AAD and providing consent?

Generally speaking, when you receive an interaction_required error it means the server requires some more information from the user to issue the tokens. To resolve you either need to let the user provide the required information (by redirecting) or change what you're asking for (reduced permissions the user has already granted consent for)

As an aside - v1 and v2 use different underlying auth flows, it's not going to be a 1:1 upgrade

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Jul 15, 2024
@renu10-dot
Copy link
Author

For the first time when login() is called it is redirected to AAD and gets the token back. We are calling LoginSilent() after 50mins(before 10 mins of token expire) so I can see its causing InteractionError as per above screenshot.
@tnorling I have one more doubt, as I said in msal v1 its was saved msal.idtoken in sessionstorage by msal lib and in v2 I did not find that . I created variable msalToken and saved token returned by AAD in this variable in sessionStorage. does it causing issue when we are calling acquireTokenSilent and it is not able to read cached token?
in V2 is there any way we can log msal.idtoken by msal package same as v1? so we can read from sessionStorage.getItem() in interceptor and send for api calls.
Is there any api permissions required when we call acquireTokenSilent for application.
When I googled the issue and tried to debug it I came across all above possibilities. Could you plz guide in this.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 Awaiting response from the MSAL.js team and removed Needs: Author Feedback Awaiting response from issue author labels Jul 19, 2024
@renu10-dot
Copy link
Author

renu10-dot commented Jul 22, 2024

main.js:1 [Mon, 22 Jul 2024 12:00:10 GMT] : [4dcb0723-96ad-4e3e-a862-47c9b3ffb15c] : @azure/msal-browser@2.39.0 : Info - PerformanceClient: No correlation id provided for initializeClientApplication, generating
main.js:1 [Mon, 22 Jul 2024 12:00:10 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:initializeStart
main.js:1 [Mon, 22 Jul 2024 12:00:10 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:initializeEnd
main.js:1 [Mon, 22 Jul 2024 12:00:10 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:handleRedirectStart

main.js:1 [Mon, 22 Jul 2024 12:00:10 GMT] : [0af849cd-6931-4eea-87a3-d34dd8907476] : @azure/msal-common@13.3.3 : Info - in acquireToken call in auth-code client
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-browser@2.39.0 : Info - BrowserCacheManager: addTokenKey - idToken added to map
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-browser@2.39.0 : Info - BrowserCacheManager: addTokenKey - accessToken added to map
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-browser@2.39.0 : Info - BrowserCacheManager: addTokenKey - refreshToken added to map
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:loginSuccess
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:handleRedirectEnd
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 Account:- ObjectauthorityType: "MSSTS"environment: "login.windows.net"homeAccountId: "cd24c2b5-c829-400e-84ec-6d428e4e3acb.4cc65fd6-9c76-4871-main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token

main.js:1 [Mon, 22 Jul 2024 12:00:11 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token

main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token

main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 12:00:12 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token

main.js:1 Login Silent called

main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:acquireTokenStart
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getIdToken - Returning id token
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getAccessToken - No token found
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getRefreshToken - returning refresh token
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : [29c332b8-63b8-4e49-882e-46ef9029150d] : @azure/msal-common@13.3.3 : Info - SilentFlowClient:acquireCachedToken - No access token found in cache for the given properties.
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:acquireTokenFromNetworkStart
main.js:1 [Mon, 22 Jul 2024 14:06:49 GMT] : @azure/msal-common@13.3.3 : Info - CacheManager:getRefreshToken - returning refresh token
login.microsoftonline.com/4cc65fd6-9c76-4871-a542-eb12a5a7800c/oauth2/v2.0/token:1

    Failed to load resource: net::ERR_NAME_NOT_RESOLVED

main.js:1 [Mon, 22 Jul 2024 14:07:06 GMT] : @azure/msal-browser@2.39.0 : Info - Emitting event: msal:acquireTokenFailure
main.js:1 TokenResponse:- B__zone_symbol__state: true__zone_symbol__value: undefinedSymbol(Symbol.species): (...)Symbol(Symbol.toStringTag): (...)

I can see from logs its not getting accessToken from cache
@tnorling can you plz guide what I am doing wrong . I have shared all code .

@tnorling
Copy link
Collaborator

For the first time when login() is called it is redirected to AAD and gets the token back. We are calling LoginSilent() after 50mins(before 10 mins of token expire) so I can see its causing InteractionError as per above screenshot. @tnorling I have one more doubt, as I said in msal v1 its was saved msal.idtoken in sessionstorage by msal lib and in v2 I did not find that . I created variable msalToken and saved token returned by AAD in this variable in sessionStorage. does it causing issue when we are calling acquireTokenSilent and it is not able to read cached token? in V2 is there any way we can log msal.idtoken by msal package same as v1? so we can read from sessionStorage.getItem() in interceptor and send for api calls. Is there any api permissions required when we call acquireTokenSilent for application. When I googled the issue and tried to debug it I came across all above possibilities. Could you plz guide in this.

You should not be storing or looking up tokens in local/session storage. Caching is an implementation detail of the library and keys/values are subject to change at any time. When you need a token you should invoke acquireTokenSilent, it will return the token from the cache if available and if it returns InteractionRequired error you should catch this and invoke acquireTokenRedirect or acquireTokenPopup to resolve.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Aug 14, 2024
Copy link
Contributor

@renu10-dot This issue has been automatically marked as stale because it is marked as requiring author feedback but has not had any activity for 5 days. If your issue has been resolved please let us know by closing the issue. If your issue has not been resolved please leave a comment to keep this open. It will be closed automatically in 7 days if it remains stale.

@microsoft-github-policy-service microsoft-github-policy-service bot added the no-issue-activity Issue author has not responded in 5 days label Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug-unconfirmed A reported bug that needs to be investigated and confirmed msal-angular Related to @azure/msal-angular package msal-browser Related to msal-browser package Needs: Author Feedback Awaiting response from issue author no-issue-activity Issue author has not responded in 5 days public-client Issues regarding PublicClientApplications question Customer is asking for a clarification, use case or information.
Projects
None yet
Development

No branches or pull requests

2 participants