use of com.microsoft.identity.common.internal.dto.IdTokenRecord in project microsoft-authentication-library-common-for-android by AzureAD.
the class MsalOAuth2TokenCache method load.
@Override
public ICacheRecord load(@NonNull final String clientId, @Nullable final String target, @NonNull final AccountRecord account, @NonNull final AbstractAuthenticationScheme authScheme) {
Telemetry.emit(new CacheStartEvent());
final boolean isMultiResourceCapable = MicrosoftAccount.AUTHORITY_TYPE_V1_V2.equals(account.getAuthorityType());
// 'Preloading' our credentials to avoid repeated expensive cache hits
final List<Credential> allCredentials = mAccountCredentialCache.getCredentials();
// Load the AccessTokens
final List<Credential> accessTokens = mAccountCredentialCache.getCredentialsFilteredBy(account.getHomeAccountId(), account.getEnvironment(), getAccessTokenCredentialTypeForAuthenticationScheme(authScheme), clientId, account.getRealm(), target, authScheme.getName(), allCredentials);
// Load the RefreshTokens
List<Credential> refreshTokens = mAccountCredentialCache.getCredentialsFilteredBy(account.getHomeAccountId(), account.getEnvironment(), CredentialType.RefreshToken, clientId, isMultiResourceCapable ? // wildcard (*)
null : account.getRealm(), isMultiResourceCapable ? // wildcard (*)
null : target, // not applicable
null, allCredentials);
if (refreshTokens.isEmpty()) {
// If we didn't find an RT in the cache, this could be a "TSL-seed" or "dual-client stack"
// scenario
//
// Defining these terms:
// TSL-seed: another 1P TSL integrated app has put a token into our cache so we can
// pick it up
//
// Dual-Client stack: two FoCI-enabled app registrations are sharing a single binary
// and accordingly, can share RTs.
// Examples for this might be TFL/TFW - which uses multiple client ids to enable
// different scenarios depending on enterprise vs. consumer usage
// Unlike the broker, where we check if an app is FoCI prior to making a network call
// with an arbitrary FoCI RT we find in the cache, if we're in standalone mode and find
// a FoCI RT in the cache, the current app must also be FoCI (!!!)
//
// Making the assumption that the current client id can use any FoCI RT we find in the
// cache is strictly contingent that app developers NOT mix FoCI/non-FoCI registrations
// into same binary. If you do this, you'll get confusing errors that the RT used doesn't
// match the client app registration. This assumption means we don't need to implement
// "FoCI probing" and/or track FoCI app meta
final Credential fallbackFrt = getFamilyRefreshTokenForAccount(account);
if (null != fallbackFrt) {
refreshTokens = new ArrayList<>();
refreshTokens.add(fallbackFrt);
}
}
// Load the IdTokens
final List<Credential> idTokens = mAccountCredentialCache.getCredentialsFilteredBy(account.getHomeAccountId(), account.getEnvironment(), IdToken, clientId, account.getRealm(), // wildcard (*),
null, // not applicable
null, allCredentials);
// Load the v1 IdTokens
final List<Credential> v1IdTokens = mAccountCredentialCache.getCredentialsFilteredBy(account.getHomeAccountId(), account.getEnvironment(), CredentialType.V1IdToken, clientId, account.getRealm(), // wildcard (*)
null, // not applicable
null, allCredentials);
final CacheRecord.CacheRecordBuilder result = CacheRecord.builder();
result.account(account);
result.accessToken(accessTokens.isEmpty() ? null : (AccessTokenRecord) accessTokens.get(0));
result.refreshToken(refreshTokens.isEmpty() ? null : (RefreshTokenRecord) refreshTokens.get(0));
result.idToken(idTokens.isEmpty() ? null : (IdTokenRecord) idTokens.get(0));
result.v1IdToken(v1IdTokens.isEmpty() ? null : (IdTokenRecord) v1IdTokens.get(0));
Telemetry.emit(new CacheEndEvent().putCacheRecordStatus(result.build()));
return result.build();
}
use of com.microsoft.identity.common.internal.dto.IdTokenRecord in project microsoft-authentication-library-common-for-android by AzureAD.
the class MsalOAuth2TokenCache method getAccountsWithAggregatedAccountData.
@Override
public List<ICacheRecord> getAccountsWithAggregatedAccountData(@Nullable final String environment, @NonNull final String clientId) {
final String methodName = ":getAccountsWithAggregatedAccountData";
final List<ICacheRecord> result = new ArrayList<>();
final List<AccountRecord> allMatchingAccounts = getAccounts(environment, clientId);
for (final AccountRecord accountRecord : allMatchingAccounts) {
final List<IdTokenRecord> idTokensForAccount = getIdTokensForAccountRecord(clientId, accountRecord);
if (idTokensForAccount == null || idTokensForAccount.size() == 0) {
// Skip returning account record if there is no corresponding idToken record in the cache for the given clientId
continue;
}
// Construct the cache record....
final CacheRecord.CacheRecordBuilder cacheRecordBuilder = CacheRecord.builder();
cacheRecordBuilder.account(accountRecord);
// Set the IdTokens...
for (IdTokenRecord idTokenRecord : idTokensForAccount) {
setToCacheRecord(cacheRecordBuilder, idTokenRecord);
}
result.add(cacheRecordBuilder.build());
}
Logger.verbose(TAG + methodName, "Found " + result.size() + " accounts with IdTokens");
return Collections.unmodifiableList(result);
}
use of com.microsoft.identity.common.internal.dto.IdTokenRecord in project microsoft-authentication-library-common-for-android by AzureAD.
the class MsalOAuth2TokenCache method getSparseCacheRecordForAccount.
/**
* Given an AccountRecord and associated client_id, load a sparse ICacheRecord containing
* the provided AccountRecord and its accompanying IdTokens. "Sparse" here indicates that any
* accompanying access tokens or refresh tokens will not be loaded into the ICacheRecord.
*
* @param clientId The client_id relative to which IdTokens should be loaded.
* @param acct The target AccountRecord.
* @return A sparse ICacheRecord containing the provided AccountRecord and its IdTokens.
*/
ICacheRecord getSparseCacheRecordForAccount(@NonNull final String clientId, @NonNull final AccountRecord acct) {
final String methodName = ":getSparseCacheRecordForAccount";
final List<IdTokenRecord> acctIdTokens = getIdTokensForAccountRecord(clientId, acct);
if (acctIdTokens.size() > ID_TOKEN_TYPES.length) {
// We shouldn't have more idtokens than types of idtokens... 1 each
Logger.warn(TAG + methodName, "Found more IdTokens than expected." + "\nFound: [" + acctIdTokens.size() + "]");
}
final CacheRecord.CacheRecordBuilder associatedRecord = CacheRecord.builder();
associatedRecord.account(acct);
for (final IdTokenRecord idTokenRecord : acctIdTokens) {
setToCacheRecord(associatedRecord, idTokenRecord);
}
return associatedRecord.build();
}
use of com.microsoft.identity.common.internal.dto.IdTokenRecord in project microsoft-authentication-library-common-for-android by AzureAD.
the class MsalOAuth2TokenCache method getIdTokensForAccountRecord.
@Override
public List<IdTokenRecord> getIdTokensForAccountRecord(@Nullable String clientId, @NonNull AccountRecord accountRecord) {
final List<IdTokenRecord> result = new ArrayList<>();
final List<Credential> allCredentials = mAccountCredentialCache.getCredentials();
final List<Credential> idTokens = mAccountCredentialCache.getCredentialsFilteredBy(accountRecord.getHomeAccountId(), accountRecord.getEnvironment(), IdToken, // If null, behaves as wildcard
clientId, accountRecord.getRealm(), // wildcard (*),
null, // not applicable
null, allCredentials);
idTokens.addAll(mAccountCredentialCache.getCredentialsFilteredBy(accountRecord.getHomeAccountId(), accountRecord.getEnvironment(), CredentialType.V1IdToken, clientId, accountRecord.getRealm(), // wildcard (*)
null, // not applicable
null, allCredentials));
for (final Credential credential : idTokens) {
if (credential instanceof IdTokenRecord) {
result.add((IdTokenRecord) credential);
}
}
return Collections.unmodifiableList(result);
}
use of com.microsoft.identity.common.internal.dto.IdTokenRecord in project microsoft-authentication-library-common-for-android by AzureAD.
the class MicrosoftFamilyOAuth2TokenCache method loadByFamilyIdWithAggregatedAccountData.
public List<ICacheRecord> loadByFamilyIdWithAggregatedAccountData(@NonNull final String clientId, @Nullable final String target, @NonNull final AccountRecord account, @Nullable final AbstractAuthenticationScheme authenticationScheme) {
final String methodName = ":loadByFamilyIdWithAggregatedAccountData";
final List<ICacheRecord> result = new ArrayList<>();
// First, load our primary record...
result.add(loadByFamilyId(clientId, target, account, authenticationScheme));
// We also want to add accounts from different realms...
final List<AccountRecord> accountsInOtherTenants = new ArrayList<>(getAllTenantAccountsForAccountByClientId(clientId, account));
Logger.info(TAG + methodName, "Found " + (accountsInOtherTenants.size() - 1) + " profiles for this account");
// Ignore the first element, as it will contain the same result as loadByFamilyId()....
accountsInOtherTenants.remove(0);
if (!accountsInOtherTenants.isEmpty()) {
for (final AccountRecord accountRecord : accountsInOtherTenants) {
// Declare our container
final CacheRecord.CacheRecordBuilder cacheRecord = CacheRecord.builder();
cacheRecord.mAccount(accountRecord);
cacheRecord.refreshToken(result.get(0).getRefreshToken());
// Load all of the IdTokens and set as appropriate...
final List<IdTokenRecord> idTokensForAccount = getIdTokensForAccountRecord(clientId, accountRecord);
for (final IdTokenRecord idTokenRecord : idTokensForAccount) {
if (CredentialType.V1IdToken.name().equalsIgnoreCase(idTokenRecord.getCredentialType())) {
cacheRecord.v1IdToken(idTokenRecord);
} else {
cacheRecord.idToken(idTokenRecord);
}
}
// We can ignore the A/T, since this account isn't being authorized...
result.add(cacheRecord.build());
}
}
return result;
}
Aggregations