Skip to content

[v5] Changes to Configuration - CacheOptions (Config #2) #7697

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

Open
wants to merge 28 commits into
base: msal-v5
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0cb8305
Deprecate temporaryCacheLocation
jo-arroyo Apr 12, 2025
becbd55
Remove storeAuthStateInCookie
jo-arroyo Apr 12, 2025
9ecf558
Remove secureCookies docs
jo-arroyo Apr 12, 2025
279d602
Remove cacheMigrationEnabled
jo-arroyo Apr 12, 2025
91f9f57
Deprecate claimsBasedCachingEnabled
jo-arroyo Apr 12, 2025
b581414
Format:fix
jo-arroyo Apr 12, 2025
a0187a4
Change files
jo-arroyo Apr 12, 2025
6bf2b16
Merge branch 'msal-v5' into config-change-cache
jo-arroyo Apr 15, 2025
d6931e4
Merge branch 'msal-v5' into config-change-cache
jo-arroyo Apr 15, 2025
bac042d
apiExtractor
jo-arroyo Apr 15, 2025
385b4d5
Merge branch 'msal-v5' into config-change-cache
jo-arroyo Apr 16, 2025
e0f8803
Update apiExtractor after merge
jo-arroyo Apr 16, 2025
2bc9137
Merge branch 'msal-v5' into config-change-cache
jo-arroyo Apr 16, 2025
cd106bc
Update apiExtractor after merge
jo-arroyo Apr 16, 2025
88e033a
Merge branch 'msal-v5' of https://github.com/AzureAD/microsoft-authen…
jo-arroyo Apr 22, 2025
4539d7d
Remove temporaryCacheLocation and claimsBasedCachingEnabled options a…
jo-arroyo Apr 23, 2025
a3fb3fc
Format and lint
jo-arroyo Apr 23, 2025
9e89fb9
Update apiExtractor
jo-arroyo Apr 23, 2025
431bced
Merge branch 'msal-v5' of https://github.com/AzureAD/microsoft-authen…
jo-arroyo Apr 24, 2025
e13705c
Merge branch 'msal-v5' of https://github.com/AzureAD/microsoft-authen…
jo-arroyo Apr 25, 2025
cdf34c1
Merge branch 'msal-v5' of https://github.com/AzureAD/microsoft-authen…
jo-arroyo Apr 29, 2025
79e0a34
Update tests for not caching claims
jo-arroyo Apr 29, 2025
00a3f90
Remove e2e test for redirects with memory storage as not supported
jo-arroyo May 2, 2025
5864f6c
Update lib/msal-browser/docs/caching.md
jo-arroyo May 2, 2025
35cb314
Remove CacheOptions as empty
jo-arroyo May 2, 2025
48373e6
Merge branch 'config-change-cache' of https://github.com/AzureAD/micr…
jo-arroyo May 2, 2025
4ccb22b
Remove setting requestedClaimsHash with claimsBasedCachingEnabled flag
jo-arroyo May 9, 2025
8ac7249
Fix linting
jo-arroyo May 9, 2025
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
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ body:
},
cache: {
cacheLocation: "sessionStorage"
storeAuthStateInCookie: false
}
}
validations:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "major",
"comment": "Configuration changes to CacheOptions #7697",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Deprecate claimsBasedCachingEnabled as part of Configuration change #7697",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
3 changes: 0 additions & 3 deletions lib/msal-angular/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: true, // Deprecated, will be removed in the next major version
},
system: {
loggerOptions: {
Expand Down Expand Up @@ -261,7 +260,6 @@ fetch("/assets/configuration.json")
},
"cache": {
"cacheLocation": "localStorage",
"storeAuthStateInCookie": true
}
},
"guard": {
Expand Down Expand Up @@ -471,7 +469,6 @@ export class AppModule {}
},
"cache": {
"cacheLocation": "localStorage",
"storeAuthStateInCookie": true
}
},
"guard": {
Expand Down
1 change: 0 additions & 1 deletion lib/msal-angular/docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "
},
cache: {
cacheLocation : BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: true, // set to true for IE 11
},
system: {
loggerOptions: {
Expand Down
2 changes: 0 additions & 2 deletions lib/msal-angular/docs/initialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "
},
cache: {
cacheLocation : BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: true, // Deprecated, will be removed in future version
},
system: {
loggerOptions: {
Expand Down Expand Up @@ -115,7 +114,6 @@ import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "
},
cache: {
cacheLocation : BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: true, // Deprecated, will be removed in future version
},
system: {
loggerOptions: {
Expand Down
6 changes: 1 addition & 5 deletions lib/msal-browser/apiReview/msal-browser.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,6 @@ export type CacheLookupPolicy = (typeof CacheLookupPolicy)[keyof typeof CacheLoo
// @public
export type CacheOptions = {
cacheLocation?: BrowserCacheLocation | string;
temporaryCacheLocation?: BrowserCacheLocation | string;
storeAuthStateInCookie?: boolean;
cacheMigrationEnabled?: boolean;
claimsBasedCachingEnabled?: boolean;
};

// Warning: (ae-missing-release-tag) "ClearCacheRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand Down Expand Up @@ -1491,7 +1487,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU];
// src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/config/Configuration.ts:256:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts
// src/config/Configuration.ts:211:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts
// src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@"
Expand Down
12 changes: 1 addition & 11 deletions lib/msal-browser/docs/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,10 @@ To faciliate efficient token acquisition while maintaining a good UX, MSAL cache
- previous failed request
- performance data

> :bulb: Temporary cache entries will always be stored in session storage or in memory unless overridden by the user with the `temporaryCacheLocation` cache option. MSAL will fallback to memory storage if local/session storage is not available. Please read the warning below for more information.
> :bulb: Temporary cache entries will always be stored in session storage or in memory. MSAL will fallback to memory storage if sessionStorage is not available.

> :bulb: The authorization code is only stored in memory and will be discarded after redeeming it for tokens.

## Warning :warning:

**NOTE: `temporaryCacheLocation` is deprecated will be removed in the next major version.**

Overriding `temporaryCacheLocation` should be done with caution. Specifically when choosing `localStorage`. Interaction in more than one tab/window will not be supported and you may receive `interaction_in_progress` errors unexpectedly. This is an escape hatch, not a fully supported feature.

When using MSAL.js with the default configuration in a scenario where the user is redirected after successful authentication in a new window or tab, the OAuth 2.0 Authorization Code with PKCE flow will be interrupted. In this case, the original window or tab where the authentication state (code verifier and challenge) are stored, will be lost, and the authentication flow will fail.

To handle this scenario, you can configure MSAL to use `localStorage` as the cache location by overriding the `temporaryCacheLocation` configuration property. This allows the code verifier and challenge to be stored in the browser's `localStorage,` which is persistent across multiple tabs and windows.

## Remarks

- We do not recommend apps having business logic dependent on direct use of entities in the cache. Instead, use the appropriate MSAL API when you need to acquire tokens or retrieve accounts.
Expand Down
14 changes: 0 additions & 14 deletions lib/msal-browser/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ const msalConfig = {
},
cache: {
cacheLocation: "sessionStorage",
temporaryCacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
secureCookies: false,
claimsBasedCachingEnabled: true,
},
system: {
loggerOptions: {
Expand Down Expand Up @@ -96,16 +92,6 @@ const msalInstance = new PublicClientApplication(msalConfig);
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `cacheLocation` | Location of token cache in browser. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` |

**Note: The following cache config options are deprecated and will be removed in the next major version**

| Option | Description | Format | Default Value |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `temporaryCacheLocation` | Location of temporary cache in browser. This option should only be changed for specific edge cases. Please refer to [caching](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/caching.md#cached-artifacts) for more. | String value that must be one of the following: `"sessionStorage"`, `"localStorage"`, `"memoryStorage"` | `sessionStorage` |
| `storeAuthStateInCookie` | If true, stores cache items in cookies as well as browser cache. Should be set to true for use cases using IE. | boolean | `false` |
| `secureCookies` | If true and `storeAuthStateInCookies` is also enabled, MSAL adds the `Secure` flag to the browser cookie so it can only be sent over HTTPS. | boolean | `false` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off the topic, but related. Can we make sure the one cookie we set for KMSI is the only one we manage and add it to the docs under cookies MSAL JS manages.. etc. Also link to the migration guide on the discontinuation of existing cookies.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually tested to ensure that KMSI is the only cookie set and managed. Migration guide will come in a different PR but will make a note this is mentioned.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was some registration work that Thomas had to do for the KMSI cookie. Did we not have any 1p users using this functionality? Or did they just not reach out to us that they were using it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought they did, atleast OWA who tested KMSI.

| `cacheMigrationEnabled` | If true, cache entries from older versions of MSAL will be updated to conform to the latest cache schema on startup. If your application has not been recently updated to a new version of MSAL.js you can safely turn this off. In the event old cache entries are not migrated it may result in a cache miss when attempting to retrieve accounts or tokens and affected users may need to re-authenticate to get up to date. | boolean | `true` when using `localStorage`, `false` otherwise |
| `claimsBasedCachingEnabled` | If `true`, access tokens will be cached under a key containing the hash of the requested claims string, resulting in a cache miss and new network token request when the same token request is made with different or missing claims. If set to `false`, tokens will be cached without claims, but all requests containing claims will go to the network and overwrite any previously cached token with the same scopes. | boolean | `false` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us ensure we test this, that we never cache claims. I want to make sure we have Loop who had this bug before, and Teams who I think are setting this to false are not broken with v5.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sameerag See tests added below to ensure no claims cached.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get claims removed from the cache key as well if we're removing the functionality. Doesn't need to be in this PR, or even a requisite before GA, but let's note it somewhere so we can clean it up at some point

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend this before we GA v5. Otherwise, it sounds like we could have some cache behavior changes after removing claims from the cache key.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining a model for changes like that is what I'm working on now, we need to be able to make cache changes anytime so I don't feel strongly that it needs to happen right away but if we want to plan that in as part of the GA that's totally cool :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to make this a gating feature for GA. @tnorling so this means you will also consider folks transitioning from claims cached to none in your work too?


See [Caching in MSAL](./caching.md) for more.

### System Config Options
Expand Down
3 changes: 1 addition & 2 deletions lib/msal-browser/docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,5 +437,4 @@ This error occurs when MSAL.js surpasses the allotted storage limit when attempt

**Mitigation**:

1. Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts).
2. Disable [claimsBasedCachingEnabled](./configuration.md#cache-config-options) cache config option. When enabled, it caches access tokens under a key containing the hash of the requested claims. Depending on the MSAL.js API usage, it may result in the vast number of access tokens persisted in the cache storage.
Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts).
35 changes: 1 addition & 34 deletions lib/msal-browser/src/cache/BrowserCacheManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ import { EventHandler } from "../event/EventHandler.js";

/**
* This class implements the cache storage interface for MSAL through browser local or session storage.
* Cookies are only used if storeAuthStateInCookie is true, and are only used for
* parameters such as state and nonce, generally.
*/
export class BrowserCacheManager extends CacheManager {
// Cache configuration, either set by user or default values.
Expand Down Expand Up @@ -111,7 +109,7 @@ export class BrowserCacheManager extends CacheManager {
);
this.temporaryCacheStorage = getStorageImplementation(
clientId,
cacheConfig.temporaryCacheLocation,
BrowserCacheLocation.SessionStorage,
logger,
performanceClient
);
Expand Down Expand Up @@ -889,21 +887,10 @@ export class BrowserCacheManager extends CacheManager {

/**
* Gets cache item with given key.
* Will retrieve from cookies if storeAuthStateInCookie is set to true.
* @param key
*/
getTemporaryCache(cacheKey: string, generateKey?: boolean): string | null {
const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey;
if (this.cacheConfig.storeAuthStateInCookie) {
const itemCookie = this.cookieStorage.getItem(key);
if (itemCookie) {
this.logger.trace(
"BrowserCacheManager.getTemporaryCache: storeAuthStateInCookies set to true, retrieving from cookies"
);
return itemCookie;
}
}

const value = this.temporaryCacheStorage.getItem(key);
if (!value) {
// If temp cache item not found in session/memory, check local storage for items set by old versions
Expand Down Expand Up @@ -932,8 +919,6 @@ export class BrowserCacheManager extends CacheManager {

/**
* Sets the cache item with the key and value given.
* Stores in cookie if storeAuthStateInCookie is set to true.
* This can cause cookie overflow if used incorrectly.
* @param key
* @param value
*/
Expand All @@ -943,14 +928,7 @@ export class BrowserCacheManager extends CacheManager {
generateKey?: boolean
): void {
const key = generateKey ? this.generateCacheKey(cacheKey) : cacheKey;

this.temporaryCacheStorage.setItem(key, value);
if (this.cacheConfig.storeAuthStateInCookie) {
this.logger.trace(
"BrowserCacheManager.setTemporaryCache: storeAuthStateInCookie set to true, setting item cookie"
);
this.cookieStorage.setItem(key, value, undefined);
}
}

/**
Expand All @@ -963,17 +941,10 @@ export class BrowserCacheManager extends CacheManager {

/**
* Removes the temporary cache item with the given key.
* Will also clear the cookie item if storeAuthStateInCookie is set to true.
* @param key
*/
removeTemporaryItem(key: string): void {
this.temporaryCacheStorage.removeItem(key);
if (this.cacheConfig.storeAuthStateInCookie) {
this.logger.trace(
"BrowserCacheManager.removeItem: storeAuthStateInCookie is true, clearing item cookie"
);
this.cookieStorage.removeItem(key);
}
}

/**
Expand Down Expand Up @@ -1373,10 +1344,6 @@ export const DEFAULT_BROWSER_CACHE_MANAGER = (
): BrowserCacheManager => {
const cacheOptions: Required<CacheOptions> = {
cacheLocation: BrowserCacheLocation.MemoryStorage,
temporaryCacheLocation: BrowserCacheLocation.MemoryStorage,
storeAuthStateInCookie: false,
cacheMigrationEnabled: false,
claimsBasedCachingEnabled: false,
};
return new BrowserCacheManager(
clientId,
Expand Down
29 changes: 0 additions & 29 deletions lib/msal-browser/src/config/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,26 +113,6 @@ export type CacheOptions = {
* Used to specify the cacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage".
*/
cacheLocation?: BrowserCacheLocation | string;
/**
* Used to specify the temporaryCacheLocation user wants to set. Valid values are "localStorage", "sessionStorage" and "memoryStorage".
* @deprecated This option is deprecated and will be removed in the next major version.
*/
temporaryCacheLocation?: BrowserCacheLocation | string;
/**
* If set, MSAL stores the auth request state required for validation of the auth flows in the browser cookies. By default this flag is set to false.
* @deprecated This option is deprecated and will be removed in the next major version.
*/
storeAuthStateInCookie?: boolean;
/**
* If set, MSAL will attempt to migrate cache entries from older versions on initialization. By default this flag is set to true if cacheLocation is localStorage, otherwise false.
* @deprecated This option is deprecated and will be removed in the next major version.
*/
cacheMigrationEnabled?: boolean;
/**
* Flag that determines whether access tokens are stored based on requested claims
* @deprecated This option is deprecated and will be removed in the next major version.
*/
claimsBasedCachingEnabled?: boolean;
};

export type BrowserSystemOptions = SystemOptions & {
Expand Down Expand Up @@ -282,15 +262,6 @@ export function buildConfiguration(
// Default cache options for browser
const DEFAULT_CACHE_OPTIONS: Required<CacheOptions> = {
cacheLocation: BrowserCacheLocation.SessionStorage,
temporaryCacheLocation: BrowserCacheLocation.SessionStorage,
storeAuthStateInCookie: false,
// Default cache migration to true if cache location is localStorage since entries are preserved across tabs/windows. Migration has little to no benefit in sessionStorage and memoryStorage
cacheMigrationEnabled:
userInputCache &&
userInputCache.cacheLocation === BrowserCacheLocation.LocalStorage
? true
: false,
claimsBasedCachingEnabled: false,
};

// Default logger options for browser
Expand Down
Loading