Search in sources :

Example 61 with AccountRecord

use of com.microsoft.identity.common.internal.dto.AccountRecord in project microsoft-authentication-library-common-for-android by AzureAD.

the class LocalMSALController method acquireTokenSilent.

@Override
public AcquireTokenResult acquireTokenSilent(@NonNull final SilentTokenCommandParameters parameters) throws IOException, ClientException, ArgumentException, ServiceException {
    final String methodName = ":acquireTokenSilent";
    Logger.verbose(TAG + methodName, "Acquiring token silently...");
    Telemetry.emit(new ApiStartEvent().putProperties(parameters).putApiId(TelemetryEventStrings.Api.LOCAL_ACQUIRE_TOKEN_SILENT));
    final AcquireTokenResult acquireTokenSilentResult = new AcquireTokenResult();
    // Validate MSAL Parameters
    parameters.validate();
    // Add default scopes
    final Set<String> mergedScopes = addDefaultScopes(parameters);
    final SilentTokenCommandParameters parametersWithScopes = parameters.toBuilder().scopes(mergedScopes).build();
    @SuppressWarnings(WarningType.rawtype_warning) final OAuth2TokenCache tokenCache = parametersWithScopes.getOAuth2TokenCache();
    final AccountRecord targetAccount = getCachedAccountRecord(parametersWithScopes);
    // Build up params for Strategy construction
    final AbstractAuthenticationScheme authScheme = parametersWithScopes.getAuthenticationScheme();
    final OAuth2StrategyParameters strategyParameters = new OAuth2StrategyParameters();
    strategyParameters.setContext(parametersWithScopes.getAndroidApplicationContext());
    @SuppressWarnings(WarningType.rawtype_warning) final OAuth2Strategy strategy = parametersWithScopes.getAuthority().createOAuth2Strategy(strategyParameters);
    // Suppressing unchecked warning of converting List<ICacheRecord> to List due to generic type not provided for tokenCache
    @SuppressWarnings(WarningType.unchecked_warning) final List<ICacheRecord> cacheRecords = tokenCache.loadWithAggregatedAccountData(parametersWithScopes.getClientId(), TextUtils.join(" ", parametersWithScopes.getScopes()), targetAccount, authScheme);
    // The first element is the 'fully-loaded' CacheRecord which may contain the AccountRecord,
    // AccessTokenRecord, RefreshTokenRecord, and IdTokenRecord... (if all of those artifacts exist)
    // subsequent CacheRecords represent other profiles (projections) of this principal in
    // other tenants. Those tokens will be 'sparse', meaning that their AT/RT will not be loaded
    final ICacheRecord fullCacheRecord = cacheRecords.get(0);
    if (accessTokenIsNull(fullCacheRecord) || refreshTokenIsNull(fullCacheRecord) || parametersWithScopes.isForceRefresh() || !isRequestAuthorityRealmSameAsATRealm(parametersWithScopes.getAuthority(), fullCacheRecord.getAccessToken()) || !strategy.validateCachedResult(authScheme, fullCacheRecord)) {
        if (!refreshTokenIsNull(fullCacheRecord)) {
            // No AT found, but the RT checks out, so we'll use it
            Logger.verbose(TAG + methodName, "No access token found, but RT is available.");
            renewAccessToken(parametersWithScopes, acquireTokenSilentResult, tokenCache, strategy, fullCacheRecord);
        } else {
            // TODO need the refactor, should just throw the ui required exception, rather than
            // wrap the exception later in the exception wrapper.
            final ClientException exception = new ClientException(ErrorStrings.NO_TOKENS_FOUND, "No refresh token was found. ");
            Telemetry.emit(new ApiEndEvent().putException(exception).putApiId(TelemetryEventStrings.Api.LOCAL_ACQUIRE_TOKEN_SILENT));
            throw exception;
        }
    } else if (fullCacheRecord.getAccessToken().isExpired()) {
        Logger.warn(TAG + methodName, "Access token is expired. Removing from cache...");
        // Remove the expired token
        tokenCache.removeCredential(fullCacheRecord.getAccessToken());
        Logger.verbose(TAG + methodName, "Renewing access token...");
        // Request a new AT
        renewAccessToken(parametersWithScopes, acquireTokenSilentResult, tokenCache, strategy, fullCacheRecord);
    } else {
        Logger.verbose(TAG + methodName, "Returning silent result");
        // the result checks out, return that....
        acquireTokenSilentResult.setLocalAuthenticationResult(new LocalAuthenticationResult(finalizeCacheRecordForResult(fullCacheRecord, parametersWithScopes.getAuthenticationScheme()), cacheRecords, SdkType.MSAL, true));
    }
    Telemetry.emit(new ApiEndEvent().putResult(acquireTokenSilentResult).putApiId(TelemetryEventStrings.Api.LOCAL_ACQUIRE_TOKEN_SILENT));
    return acquireTokenSilentResult;
}
Also used : AcquireTokenResult(com.microsoft.identity.common.internal.result.AcquireTokenResult) SilentTokenCommandParameters(com.microsoft.identity.common.internal.commands.parameters.SilentTokenCommandParameters) ICacheRecord(com.microsoft.identity.common.internal.cache.ICacheRecord) OAuth2StrategyParameters(com.microsoft.identity.common.internal.providers.oauth2.OAuth2StrategyParameters) OAuth2Strategy(com.microsoft.identity.common.internal.providers.oauth2.OAuth2Strategy) AbstractAuthenticationScheme(com.microsoft.identity.common.internal.authscheme.AbstractAuthenticationScheme) OAuth2TokenCache(com.microsoft.identity.common.internal.providers.oauth2.OAuth2TokenCache) ApiEndEvent(com.microsoft.identity.common.internal.telemetry.events.ApiEndEvent) ApiStartEvent(com.microsoft.identity.common.internal.telemetry.events.ApiStartEvent) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord) ClientException(com.microsoft.identity.common.exception.ClientException) LocalAuthenticationResult(com.microsoft.identity.common.internal.result.LocalAuthenticationResult)

Example 62 with AccountRecord

use of com.microsoft.identity.common.internal.dto.AccountRecord in project microsoft-authentication-library-common-for-android by AzureAD.

the class SharedPreferencesAccountCredentialCache method getAccountsWithKeys.

@NonNull
private Map<String, AccountRecord> getAccountsWithKeys() {
    Logger.verbose(TAG, "Loading Accounts + keys...");
    final Iterator<Map.Entry<String, String>> cacheValues = mSharedPreferencesFileManager.getAllFilteredByKey(new SharedPreferencesFileManager.Predicate<String>() {

        @Override
        public boolean test(String value) {
            return isAccount(value);
        }
    });
    final Map<String, AccountRecord> accounts = new HashMap<>();
    while (cacheValues.hasNext()) {
        Map.Entry<String, ?> cacheValue = cacheValues.next();
        final String cacheKey = cacheValue.getKey();
        final AccountRecord account = mCacheValueDelegate.fromCacheValue(cacheValue.getValue().toString(), AccountRecord.class);
        if (null == account) {
            Logger.warn(TAG, ACCOUNT_RECORD_DESERIALIZATION_FAILED);
        } else {
            accounts.put(cacheKey, account);
        }
    }
    Logger.verbose(TAG, "Returning [" + accounts.size() + "] Accounts w/ keys...");
    return accounts;
}
Also used : HashMap(java.util.HashMap) IAccountRecord(com.microsoft.identity.common.internal.dto.IAccountRecord) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord) HashMap(java.util.HashMap) Map(java.util.Map) NonNull(androidx.annotation.NonNull)

Example 63 with AccountRecord

use of com.microsoft.identity.common.internal.dto.AccountRecord in project microsoft-authentication-library-common-for-android by AzureAD.

the class SharedPreferencesAccountCredentialCache method saveAccount.

@Override
public synchronized void saveAccount(@NonNull final AccountRecord accountToSave) {
    Logger.verbose(TAG, "Saving Account...");
    Logger.verbose(TAG, "Account type: [" + accountToSave.getClass().getSimpleName() + "]");
    final String cacheKey = mCacheValueDelegate.generateCacheKey(accountToSave);
    Logger.verbosePII(TAG, "Generated cache key: [" + cacheKey + "]");
    // Perform any necessary field merging on the Account to save...
    final AccountRecord existingAccount = getAccount(cacheKey);
    if (null != existingAccount) {
        accountToSave.mergeAdditionalFields(existingAccount);
    }
    final String cacheValue = mCacheValueDelegate.generateCacheValue(accountToSave);
    mSharedPreferencesFileManager.putString(cacheKey, cacheValue);
}
Also used : IAccountRecord(com.microsoft.identity.common.internal.dto.IAccountRecord) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord)

Example 64 with AccountRecord

use of com.microsoft.identity.common.internal.dto.AccountRecord in project microsoft-authentication-library-common-for-android by AzureAD.

the class SharedPreferencesAccountCredentialCache method getAccount.

@Override
public synchronized AccountRecord getAccount(@NonNull final String cacheKey) {
    Logger.verbose(TAG, "Loading Account by key...");
    AccountRecord account = mCacheValueDelegate.fromCacheValue(mSharedPreferencesFileManager.getString(cacheKey), AccountRecord.class);
    if (null == account) {
        // We could not deserialize the target AccountRecord...
        // Maybe it was encrypted for another application?
        Logger.warn(TAG, ACCOUNT_RECORD_DESERIALIZATION_FAILED);
    } else if (EMPTY_ACCOUNT.equals(account)) {
        Logger.warn(TAG, "The returned Account was uninitialized. Removing...");
        mSharedPreferencesFileManager.remove(cacheKey);
        account = null;
    }
    return account;
}
Also used : IAccountRecord(com.microsoft.identity.common.internal.dto.IAccountRecord) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord)

Example 65 with AccountRecord

use of com.microsoft.identity.common.internal.dto.AccountRecord in project microsoft-authentication-library-common-for-android by AzureAD.

the class SharedPreferencesAccountCredentialCacheTest method clearCredentials.

@Test
public void clearCredentials() {
    // Save an Account into the cache
    final AccountRecord account = new AccountRecord();
    account.setHomeAccountId(HOME_ACCOUNT_ID);
    account.setEnvironment(ENVIRONMENT);
    account.setRealm(REALM);
    account.setLocalAccountId(LOCAL_ACCOUNT_ID);
    account.setUsername(USERNAME);
    account.setAuthorityType(AUTHORITY_TYPE);
    mSharedPreferencesAccountCredentialCache.saveAccount(account);
    // Save an AccessToken into the cache
    final AccessTokenRecord accessToken = new AccessTokenRecord();
    accessToken.setRealm(REALM);
    accessToken.setTarget(TARGET);
    accessToken.setExpiresOn(EXPIRES_ON);
    accessToken.setCachedAt(CACHED_AT);
    accessToken.setHomeAccountId(HOME_ACCOUNT_ID);
    accessToken.setEnvironment(ENVIRONMENT);
    accessToken.setCredentialType(CredentialType.AccessToken.name());
    accessToken.setClientId(CLIENT_ID);
    accessToken.setSecret(SECRET);
    mSharedPreferencesAccountCredentialCache.saveCredential(accessToken);
    // Save a RefreshToken into the cache
    final RefreshTokenRecord refreshToken = new RefreshTokenRecord();
    refreshToken.setHomeAccountId(HOME_ACCOUNT_ID);
    refreshToken.setEnvironment(ENVIRONMENT);
    refreshToken.setCredentialType(CredentialType.RefreshToken.name());
    refreshToken.setClientId(CLIENT_ID);
    refreshToken.setSecret(SECRET);
    refreshToken.setTarget(TARGET);
    mSharedPreferencesAccountCredentialCache.saveCredential(refreshToken);
    // Call clearCredentials()
    mSharedPreferencesAccountCredentialCache.removeCredential(accessToken);
    mSharedPreferencesAccountCredentialCache.removeCredential(refreshToken);
    // Verify getAccounts() returns 1 item
    assertEquals(1, mSharedPreferencesAccountCredentialCache.getAccounts().size());
    // Verify getCredentials() returns zero items
    assertEquals(0, mSharedPreferencesAccountCredentialCache.getCredentials().size());
}
Also used : AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord) PrimaryRefreshTokenRecord(com.microsoft.identity.common.internal.dto.PrimaryRefreshTokenRecord) RefreshTokenRecord(com.microsoft.identity.common.internal.dto.RefreshTokenRecord) AccessTokenRecord(com.microsoft.identity.common.internal.dto.AccessTokenRecord) Test(org.junit.Test)

Aggregations

AccountRecord (com.microsoft.identity.common.internal.dto.AccountRecord)92 Test (org.junit.Test)61 ArrayList (java.util.ArrayList)20 ICacheRecord (com.microsoft.identity.common.internal.cache.ICacheRecord)11 AccessTokenRecord (com.microsoft.identity.common.internal.dto.AccessTokenRecord)11 OAuth2TokenCache (com.microsoft.identity.common.internal.providers.oauth2.OAuth2TokenCache)11 Credential (com.microsoft.identity.common.internal.dto.Credential)10 IdTokenRecord (com.microsoft.identity.common.internal.dto.IdTokenRecord)10 RefreshTokenRecord (com.microsoft.identity.common.internal.dto.RefreshTokenRecord)10 AccountDeletionRecord (com.microsoft.identity.common.internal.cache.AccountDeletionRecord)9 PrimaryRefreshTokenRecord (com.microsoft.identity.common.internal.dto.PrimaryRefreshTokenRecord)7 Nullable (androidx.annotation.Nullable)6 MsalOAuth2TokenCache (com.microsoft.identity.common.internal.cache.MsalOAuth2TokenCache)5 HashMap (java.util.HashMap)5 IAccountRecord (com.microsoft.identity.common.internal.dto.IAccountRecord)4 Context (android.content.Context)3 NonNull (androidx.annotation.NonNull)3 JsonElement (com.google.gson.JsonElement)3 JsonPrimitive (com.google.gson.JsonPrimitive)3 BearerAuthenticationSchemeInternal (com.microsoft.identity.common.internal.authscheme.BearerAuthenticationSchemeInternal)3