Skip to content
Merged
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
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ vNext
----------
- [PATCH] Translate MFA token error to UIRequiredException instead of ServiceException (#2538)
- [MINOR] Add Child Spans for Interactive Span (#2516)
- [MINOR] For MSAL CPP flows, match exact claims when deleting AT with intersecting scopes (#2548)

Version 18.2.2
----------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,4 +534,40 @@ public void saveATSansTargetThrowsException() throws ClientException {
mTestBundle.mGeneratedRefreshToken
);
}

@Test
public void saveCredentialsWithSameTargetAndDifferentClaims() throws ClientException {
mTestBundle.mGeneratedAccessToken.setRequestedClaims("TestClaims");
mCppCache.saveCredentials(
false,
mTestBundle.mGeneratedAccessToken
);

mTestBundle.mGeneratedAccessToken.setRequestedClaims(null);
mCppCache.saveCredentials(
false,
mTestBundle.mGeneratedAccessToken
);

List<Credential> credentials = mCppCache.getCredentials();
Assert.assertEquals(credentials.size(), 1);

//Clear credentials and now match exact claims
mCppCache.clearCache();

mTestBundle.mGeneratedAccessToken.setRequestedClaims("TestClaims");
mCppCache.saveCredentials(
true,
mTestBundle.mGeneratedAccessToken
);

mTestBundle.mGeneratedAccessToken.setRequestedClaims(null);
mCppCache.saveCredentials(
true,
mTestBundle.mGeneratedAccessToken
);

credentials = mCppCache.getCredentials();
Assert.assertEquals(credentials.size(), 2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ public IAccountCredentialCache getAccountCredentialCache() {
* @throws ClientException If the supplied Account or Credential are null or schema invalid.
*/
public synchronized void saveCredentials(@NonNull final Credential... credentials) throws ClientException {
saveCredentials(false, credentials);
}

/**
* @param credentials list of Credential which can include AccessTokenRecord, IdTokenRecord and RefreshTokenRecord.
* @param mustMatchExactClaims If true, match exact claims when deleting AT with intersecting scopes.
* @throws ClientException If the supplied Account or Credential are null or schema invalid.
*/
public synchronized void saveCredentials(boolean mustMatchExactClaims, @NonNull final Credential... credentials) throws ClientException {
if (credentials.length == 0) {
throw new ClientException("Credential array passed in is null or empty");
}
Expand All @@ -148,7 +157,7 @@ public synchronized void saveCredentials(@NonNull final Credential... credential
}
}

saveCredentialsInternal(credentials);
saveCredentialsInternal(mustMatchExactClaims, credentials);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1635,13 +1635,17 @@ private void saveAccounts(final AccountRecord... accounts) {
}

void saveCredentialsInternal(final Credential... credentials) {
saveCredentialsInternal(false, credentials);
}

void saveCredentialsInternal(boolean mustMatchExactClaims, final Credential... credentials) {
for (final Credential credential : credentials) {
if (credential == null) {
continue;
}

if (credential instanceof AccessTokenRecord) {
deleteAccessTokensWithIntersectingScopes((AccessTokenRecord) credential);
deleteAccessTokensWithIntersectingScopes((AccessTokenRecord) credential, mustMatchExactClaims);
}

mAccountCredentialCache.saveCredential(credential);
Expand Down Expand Up @@ -1707,7 +1711,7 @@ void validateCacheArtifacts(
}

private void deleteAccessTokensWithIntersectingScopes(
final AccessTokenRecord referenceToken) {
final AccessTokenRecord referenceToken, boolean mustMatchExactClaims) {
final String methodName = "deleteAccessTokensWithIntersectingScopes";

final List<Credential> accessTokens = mAccountCredentialCache.getCredentialsFilteredBy(
Expand All @@ -1721,6 +1725,7 @@ private void deleteAccessTokensWithIntersectingScopes(
null, // Wildcard (*)
referenceToken.getAccessTokenType(),
referenceToken.getRequestedClaims(),
mustMatchExactClaims,
mAccountCredentialCache.getCredentials()
);

Expand Down
Loading