Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions extensions/microsoft-authentication/src/common/cachePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ export class SecretStorageCachePlugin implements ICachePlugin, Disposable {
}
}

async afterCacheFailure(tokenCacheContext: TokenCacheContext): Promise<void> {
// Unlike a successful token response, a failed request does not reload the
// cache before changing it. Keep credentials written by another window
// while the request was in flight instead of overwriting them.
const data = await this._secretStorage.get(this._key);
if (data !== this._value) {
this._value = data;
tokenCacheContext.tokenCache.deserialize(data ?? '{}');
return;
}
await this.afterCacheAccess(tokenCacheContext);
}

dispose() {
this._disposable.dispose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { SecretStorageCachePlugin } from '../common/cachePlugin';
import { MsalLoggerOptions } from '../common/loggerOptions';
import { ICachedPublicClientApplication } from '../common/publicClientCache';
import { IAccountAccess } from '../common/accountAccess';
import { acquireTokenSilentWithCache } from './tokenCache';
import { MicrosoftAuthenticationTelemetryReporter } from '../common/telemetryReporter';

export class CachedPublicClientApplication implements ICachedPublicClientApplication {
Expand Down Expand Up @@ -110,7 +111,7 @@ export class CachedPublicClientApplication implements ICachedPublicClientApplica

async acquireTokenSilent(request: SilentFlowRequest): Promise<AuthenticationResult> {
this._logger.debug(`[acquireTokenSilent] [${this._clientId}] [${request.authority}] [${request.scopes.join(' ')}] [${request.account.username}] starting...`);
let result = await this._sequencer.queue(() => this._pca.acquireTokenSilent(request));
let result = await this._acquireTokenSilent(request);
this._logger.debug(`[acquireTokenSilent] [${this._clientId}] [${request.authority}] [${request.scopes.join(' ')}] [${request.account.username}] got result`);
// Check expiration of id token and if it's 5min before expiration, force a refresh.
// this is what MSAL does for access tokens already so we're just adding it for id tokens since we care about those.
Expand All @@ -127,7 +128,7 @@ export class CachedPublicClientApplication implements ICachedPublicClientApplica
// HACK: Broker doesn't support forceRefresh so we need to pass in claims which will force a refresh
? { ...request, claims: request.claims ?? '{ "id_token": {}}' }
: { ...request, forceRefresh: true };
result = await this._sequencer.queue(() => this._pca.acquireTokenSilent(newRequest));
result = await this._acquireTokenSilent(newRequest);
this._logger.debug(`[acquireTokenSilent] [${this._clientId}] [${request.authority}] [${request.scopes.join(' ')}] [${request.account.username}] got forced result`);
}
const newIdTokenExpirationInSecs = (result.idTokenClaims as { exp?: number }).exp;
Expand Down Expand Up @@ -170,6 +171,12 @@ export class CachedPublicClientApplication implements ICachedPublicClientApplica
return result;
}

private _acquireTokenSilent(request: SilentFlowRequest): Promise<AuthenticationResult> {
return this._sequencer.queue(() => this.isBrokerAvailable
? this._pca.acquireTokenSilent(request)
: acquireTokenSilentWithCache(this._pca, this._secretStorageCachePlugin, request));
}

async acquireTokenInteractive(request: InteractiveRequest): Promise<AuthenticationResult> {
this._logger.debug(`[acquireTokenInteractive] [${this._clientId}] [${request.authority}] [${request.scopes?.join(' ')}] loopbackClientOverride: ${request.loopbackClient ? 'true' : 'false'}`);
return await window.withProgress(
Expand Down
Loading