-
Notifications
You must be signed in to change notification settings - Fork 89
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
Enable unmarshaling partitioned caches #456
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
apps/internal/base/internal/storage/testdata/test_partitioned_cache.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
{ | ||
"AccountsPartition": { | ||
"0EuY9I6Pi8wVxq5awFCAHNbc_UKPtfnmXE4W54BzQPo=": { | ||
"uid.utid-login.windows.net-contoso": { | ||
"username": "John Doe", | ||
"local_account_id": "object1234", | ||
"realm": "contoso", | ||
"environment": "login.windows.net", | ||
"home_account_id": "uid.utid", | ||
"authority_type": "MSSTS" | ||
} | ||
} | ||
}, | ||
"RefreshTokensPartition": { | ||
"0EuY9I6Pi8wVxq5awFCAHNbc_UKPtfnmXE4W54BzQPo=": { | ||
"uid.utid-login.windows.net-refreshtoken-my_client_id--s2 s1 s3": { | ||
"target": "s2 s1 s3", | ||
"environment": "login.windows.net", | ||
"credential_type": "RefreshToken", | ||
"secret": "a refresh token", | ||
"client_id": "my_client_id", | ||
"home_account_id": "uid.utid" | ||
} | ||
} | ||
}, | ||
"AccessTokensPartition": { | ||
"0EuY9I6Pi8wVxq5awFCAHNbc_UKPtfnmXE4W54BzQPo=": { | ||
"uid.utid-login.windows.net-accesstoken-my_client_id-contoso-s2 s1 s3": { | ||
"environment": "login.windows.net", | ||
"credential_type": "AccessToken", | ||
"secret": "an access token", | ||
"realm": "contoso", | ||
"target": "s2 s1 s3", | ||
"client_id": "my_client_id", | ||
"cached_at": "1000", | ||
"home_account_id": "uid.utid", | ||
"extended_expires_on": "4600", | ||
"expires_on": "4600" | ||
} | ||
} | ||
}, | ||
"IDTokensPartition": { | ||
"0EuY9I6Pi8wVxq5awFCAHNbc_UKPtfnmXE4W54BzQPo=": { | ||
"uid.utid-login.windows.net-idtoken-my_client_id-contoso-": { | ||
"realm": "contoso", | ||
"environment": "login.windows.net", | ||
"credential_type": "IdToken", | ||
"secret": "header.eyJvaWQiOiAib2JqZWN0MTIzNCIsICJwcmVmZXJyZWRfdXNlcm5hbWUiOiAiSm9obiBEb2UiLCAic3ViIjogInN1YiJ9.signature", | ||
"client_id": "my_client_id", | ||
"home_account_id": "uid.utid" | ||
} | ||
} | ||
}, | ||
"AppMetadata": { | ||
"appmetadata-login.windows.net-my_client_id": { | ||
"environment": "login.windows.net", | ||
"client_id": "my_client_id", | ||
"family_id": "1" | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bgavrilMS is there a schema for partitioned caches or an example of how one should look serialized? I didn't find any, so I don't know the correct keys here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The serialized partitioned cache should look exactly like the non-partitioned cache. The partitioned cache is just an implementation detail in MSAL, so that MSAL is able to perform fast look-up.
You do this by going through the entire double dictionary and fetching the tokens. The first "key" is the partition key (ignore it) and the second key is the access token key - identical to the non-partitioned cache.
E.g. for an app access token you can have:
partition key: clientId + tenantId1
access token key: clientId + tenantId1 + resource1 and clientId + tenantId1 + resource2
partition key: clientId + tenantId2
access token key: clientId + tenantId2 + resource1 and clientId + tenantId2 + resource2
But in the serialized cache you will have only the 4 tokens with their access token keys.
@pmaytak can help here as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean that MSAL has a collection of partitions, each partition is indistinguishable from a non-partitioned cache, and MSAL should de/serialize only one partition at a time? That is to say, the partition key is an input to de/serialize?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, partition key is a cache entry key to de/serialize.
Something like this:
See app cache implementation in MSAL.NET
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MSAL Go partitions data in memory as expected however it always de/serializes all partitions. There's no way to de/serialize a single partition. Let's not proceed with this PR then, much more is required to make persistent caching work correctly with partitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MSAL.NET also de/serializes all partitions (so full internal cache). However, an L2 read only ever loads one partition. So as long as CCA is created per request, there's only ever 1 partition in the cache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm missing something here. MSAL Go gives the storage implementation opaque bytes and a suggested partition key, implying the bytes represent a single partition. If MSAL always de/serializes all partitions, a storage implementation that divided the cache across physical storage according to MSAL's suggested keys would just create redundant copies of the entire cache, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if MSAL instance (with the internal cache) is used as a singleton - then the external cache entries can have duplicate data. That's why we tell to create a new confidential client instance per request, so that the cache is empty initially and is deserialized with one partition.
This should be how it works, but MSAL.NET's implementation was not ideal. Ideally the serializer will accept a cache key, and try to serialize only that.