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;
}
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;
}
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);
}
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;
}
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());
}
Aggregations