Search in sources :

Example 21 with IdTokenRecord

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();
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord) Credential(com.microsoft.identity.common.internal.dto.Credential) CacheEndEvent(com.microsoft.identity.common.internal.telemetry.events.CacheEndEvent) RefreshTokenRecord(com.microsoft.identity.common.internal.dto.RefreshTokenRecord) AccessTokenRecord(com.microsoft.identity.common.internal.dto.AccessTokenRecord) CacheStartEvent(com.microsoft.identity.common.internal.telemetry.events.CacheStartEvent)

Example 22 with IdTokenRecord

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);
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord) ArrayList(java.util.ArrayList) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord)

Example 23 with IdTokenRecord

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();
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord)

Example 24 with IdTokenRecord

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);
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord) Credential(com.microsoft.identity.common.internal.dto.Credential) ArrayList(java.util.ArrayList)

Example 25 with IdTokenRecord

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;
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord) ArrayList(java.util.ArrayList) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord)

Aggregations

IdTokenRecord (com.microsoft.identity.common.internal.dto.IdTokenRecord)31 Test (org.junit.Test)17 AccountRecord (com.microsoft.identity.common.internal.dto.AccountRecord)10 AccessTokenRecord (com.microsoft.identity.common.internal.dto.AccessTokenRecord)9 RefreshTokenRecord (com.microsoft.identity.common.internal.dto.RefreshTokenRecord)9 Credential (com.microsoft.identity.common.internal.dto.Credential)7 PrimaryRefreshTokenRecord (com.microsoft.identity.common.internal.dto.PrimaryRefreshTokenRecord)4 ArrayList (java.util.ArrayList)4 JsonElement (com.google.gson.JsonElement)3 JsonPrimitive (com.google.gson.JsonPrimitive)3 ICacheRecord (com.microsoft.identity.common.internal.cache.ICacheRecord)3 HashMap (java.util.HashMap)3 JSONObject (org.json.JSONObject)3 ClientInfo (com.microsoft.identity.common.internal.providers.microsoft.azureactivedirectory.ClientInfo)2 JSONArray (org.json.JSONArray)2 Nullable (androidx.annotation.Nullable)1 JsonArray (com.google.gson.JsonArray)1 JsonObject (com.google.gson.JsonObject)1 StorageHelper (com.microsoft.identity.common.adal.internal.cache.StorageHelper)1 ServiceException (com.microsoft.identity.common.exception.ServiceException)1