Search in sources :

Example 11 with RefreshTokenRecord

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

the class MsalCppOAuth2TokenCache method saveCredentials.

/**
 * @param accountRecord : AccountRecord associated with the input credentials, can be null.
 * @param credentials   : list of Credential which can include AccessTokenRecord, IdTokenRecord and RefreshTokenRecord.
 * @throws ClientException : If the supplied Account or Credential are null or schema invalid.
 */
public synchronized void saveCredentials(@Nullable final AccountRecord accountRecord, @NonNull final Credential... credentials) throws ClientException {
    if (credentials == null || credentials.length == 0) {
        throw new ClientException("Credential array passed in is null or empty");
    }
    RefreshTokenRecord refreshTokenRecord = null;
    for (final Credential credential : credentials) {
        if (credential instanceof RefreshTokenRecord) {
            refreshTokenRecord = (RefreshTokenRecord) credential;
        }
        if (credential instanceof AccessTokenRecord && !isAccessTokenSchemaCompliant((AccessTokenRecord) credential)) {
            throw new ClientException(CREDENTIAL_IS_SCHEMA_NONCOMPLIANT, "AT is missing a required property.");
        }
    }
    if (accountRecord != null && refreshTokenRecord != null) {
        // MSAL C++ writes credentials first and then the account.
        // For a new account, this will not be true as the accountRecord will be null.
        // For existing accounts, we would remove the old refresh token if present.
        removeRefreshTokenIfNeeded(accountRecord, refreshTokenRecord);
    }
    saveCredentialsInternal(credentials);
}
Also used : Credential(com.microsoft.identity.common.internal.dto.Credential) RefreshTokenRecord(com.microsoft.identity.common.internal.dto.RefreshTokenRecord) ClientException(com.microsoft.identity.common.exception.ClientException) AccessTokenRecord(com.microsoft.identity.common.internal.dto.AccessTokenRecord)

Example 12 with RefreshTokenRecord

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

the class MsalOAuth2TokenCache method save.

@Override
public ICacheRecord save(@NonNull final GenericOAuth2Strategy oAuth2Strategy, @NonNull final GenericAuthorizationRequest request, @NonNull final GenericTokenResponse response) throws ClientException {
    // Create the Account
    final AccountRecord accountToSave = mAccountCredentialAdapter.createAccount(oAuth2Strategy, request, response);
    // Create the AccessToken
    final AccessTokenRecord accessTokenToSave = mAccountCredentialAdapter.createAccessToken(oAuth2Strategy, request, response);
    // Create the RefreshToken
    final RefreshTokenRecord refreshTokenToSave = mAccountCredentialAdapter.createRefreshToken(oAuth2Strategy, request, response);
    // Create the IdToken
    final IdTokenRecord idTokenToSave = mAccountCredentialAdapter.createIdToken(oAuth2Strategy, request, response);
    // Check that everything we're about to save is schema-compliant...
    validateCacheArtifacts(accountToSave, accessTokenToSave, refreshTokenToSave, idTokenToSave);
    // Save the Account and Credentials...
    saveAccounts(accountToSave);
    saveCredentialsInternal(accessTokenToSave, refreshTokenToSave, idTokenToSave);
    // Remove old refresh tokens (except for the one we just saved) if it's MRRT or FRT
    removeAllRefreshTokensExcept(accountToSave, refreshTokenToSave);
    final CacheRecord.CacheRecordBuilder result = CacheRecord.builder();
    result.account(accountToSave);
    result.accessToken(accessTokenToSave);
    result.refreshToken(refreshTokenToSave);
    setToCacheRecord(result, idTokenToSave);
    return result.build();
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord) AccountRecord(com.microsoft.identity.common.internal.dto.AccountRecord) RefreshTokenRecord(com.microsoft.identity.common.internal.dto.RefreshTokenRecord) AccessTokenRecord(com.microsoft.identity.common.internal.dto.AccessTokenRecord)

Example 13 with RefreshTokenRecord

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

the class AbstractAccountCredentialCache method getCredentialsFilteredByInternal.

protected List<Credential> getCredentialsFilteredByInternal(@Nullable final String homeAccountId, @Nullable final String environment, @Nullable final CredentialType credentialType, @Nullable final String clientId, @Nullable final String realm, @Nullable final String target, @Nullable final String authScheme, @Nullable final String requestedClaims, @NonNull final List<Credential> allCredentials) {
    final boolean mustMatchOnEnvironment = !StringExtensions.isNullOrBlank(environment);
    final boolean mustMatchOnHomeAccountId = !StringExtensions.isNullOrBlank(homeAccountId);
    final boolean mustMatchOnRealm = !StringExtensions.isNullOrBlank(realm);
    final boolean mustMatchOnTarget = !StringExtensions.isNullOrBlank(target);
    final boolean mustMatchOnClientId = !StringExtensions.isNullOrBlank(clientId);
    final boolean mustMatchOnCredentialType = null != credentialType;
    final boolean mustMatchOnAuthScheme = mustMatchOnCredentialType && !StringExtensions.isNullOrBlank(authScheme) && credentialType == CredentialType.AccessToken_With_AuthScheme;
    final boolean mustMatchOnRequestedClaims = !StringExtensions.isNullOrBlank(requestedClaims);
    Logger.verbose(TAG, "Credential lookup filtered by home_account_id? [" + mustMatchOnHomeAccountId + "]" + NEW_LINE + "Credential lookup filtered by realm? [" + mustMatchOnRealm + "]" + NEW_LINE + "Credential lookup filtered by target? [" + mustMatchOnTarget + "]" + NEW_LINE + "Credential lookup filtered by clientId? [" + mustMatchOnClientId + "]" + NEW_LINE + "Credential lookup filtered by credential type? [" + mustMatchOnCredentialType + "]" + NEW_LINE + "Credential lookup filtered by auth scheme? [" + mustMatchOnAuthScheme + "]" + NEW_LINE + "Credential lookup filtered by requested claims? [" + mustMatchOnRequestedClaims + "]");
    final List<Credential> matchingCredentials = new ArrayList<>();
    for (final Credential credential : allCredentials) {
        boolean matches = true;
        if (mustMatchOnHomeAccountId) {
            matches = equalsIgnoreCaseTrimBoth(homeAccountId, credential.getHomeAccountId());
        }
        if (mustMatchOnEnvironment) {
            matches = matches && equalsIgnoreCaseTrimBoth(environment, credential.getEnvironment());
        }
        if (mustMatchOnCredentialType) {
            matches = matches && equalsIgnoreCaseTrimBoth(credentialType.name(), credential.getCredentialType());
        }
        if (mustMatchOnClientId) {
            matches = matches && equalsIgnoreCaseTrimBoth(clientId, credential.getClientId());
        }
        if (mustMatchOnRealm && credential instanceof AccessTokenRecord) {
            final AccessTokenRecord accessToken = (AccessTokenRecord) credential;
            matches = matches && equalsIgnoreCaseTrimBoth(realm, accessToken.getRealm());
        }
        if (mustMatchOnRealm && credential instanceof IdTokenRecord) {
            final IdTokenRecord idToken = (IdTokenRecord) credential;
            matches = matches && equalsIgnoreCaseTrimBoth(realm, idToken.getRealm());
        }
        if (mustMatchOnTarget) {
            if (credential instanceof AccessTokenRecord) {
                final AccessTokenRecord accessToken = (AccessTokenRecord) credential;
                matches = matches && targetsIntersect(target, accessToken.getTarget(), true);
            } else if (credential instanceof RefreshTokenRecord) {
                final RefreshTokenRecord refreshToken = (RefreshTokenRecord) credential;
                matches = matches && targetsIntersect(target, refreshToken.getTarget(), true);
            } else {
                Logger.verbose(TAG, "Query specified target-match, but no target to match.");
            }
        }
        if (mustMatchOnAuthScheme && credential instanceof AccessTokenRecord) {
            final AccessTokenRecord accessToken = (AccessTokenRecord) credential;
            String atType = accessToken.getAccessTokenType();
            if (null != atType) {
                atType = atType.trim();
            }
            matches = matches && authScheme.equalsIgnoreCase(atType);
        }
        if (mustMatchOnRequestedClaims) {
            if (credential instanceof AccessTokenRecord) {
                final AccessTokenRecord accessToken = (AccessTokenRecord) credential;
                matches = matches && equalsIgnoreCaseTrimBoth(requestedClaims, accessToken.getRequestedClaims());
            } else {
                Logger.verbose(TAG, "Query specified requested_claims-match, but attempted to match with non-AT credential type.");
            }
        }
        if (matches) {
            matchingCredentials.add(credential);
        }
    }
    return matchingCredentials;
}
Also used : IdTokenRecord(com.microsoft.identity.common.internal.dto.IdTokenRecord) Credential(com.microsoft.identity.common.internal.dto.Credential) ArrayList(java.util.ArrayList) PrimaryRefreshTokenRecord(com.microsoft.identity.common.internal.dto.PrimaryRefreshTokenRecord) RefreshTokenRecord(com.microsoft.identity.common.internal.dto.RefreshTokenRecord) AccessTokenRecord(com.microsoft.identity.common.internal.dto.AccessTokenRecord)

Example 14 with RefreshTokenRecord

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

the class BaseController method renewAccessToken.

protected void renewAccessToken(@NonNull final SilentTokenCommandParameters parameters, @NonNull final AcquireTokenResult acquireTokenSilentResult, @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2TokenCache tokenCache, @SuppressWarnings(WarningType.rawtype_warning) @NonNull final OAuth2Strategy strategy, @NonNull final ICacheRecord cacheRecord) throws IOException, ClientException {
    final String methodName = ":renewAccessToken";
    Logger.info(TAG + methodName, "Renewing access token...");
    RefreshTokenRecord refreshTokenRecord = cacheRecord.getRefreshToken();
    logParameters(TAG, parameters);
    final TokenResult tokenResult = performSilentTokenRequest(strategy, refreshTokenRecord, parameters);
    acquireTokenSilentResult.setTokenResult(tokenResult);
    logResult(TAG + methodName, tokenResult);
    if (tokenResult.getSuccess()) {
        Logger.info(TAG + methodName, "Token request was successful");
        // Suppressing unchecked warnings due to casting of rawtypes to generic types of OAuth2TokenCache's instance tokenCache while calling method saveAndLoadAggregatedAccountData
        @SuppressWarnings(WarningType.unchecked_warning) final List<ICacheRecord> savedRecords = tokenCache.saveAndLoadAggregatedAccountData(strategy, getAuthorizationRequest(strategy, parameters), tokenResult.getTokenResponse());
        final ICacheRecord savedRecord = savedRecords.get(0);
        // Create a new AuthenticationResult to hold the saved record
        final LocalAuthenticationResult authenticationResult = new LocalAuthenticationResult(finalizeCacheRecordForResult(savedRecord, parameters.getAuthenticationScheme()), savedRecords, parameters.getSdkType(), false);
        // Set the client telemetry...
        if (null != tokenResult.getCliTelemInfo()) {
            final CliTelemInfo cliTelemInfo = tokenResult.getCliTelemInfo();
            authenticationResult.setSpeRing(cliTelemInfo.getSpeRing());
            authenticationResult.setRefreshTokenAge(cliTelemInfo.getRefreshTokenAge());
            Telemetry.emit(new CacheEndEvent().putSpeInfo(tokenResult.getCliTelemInfo().getSpeRing()));
        } else {
            // we can't put SpeInfo as the CliTelemInfo is null
            Telemetry.emit(new CacheEndEvent());
        }
        // Set the AuthenticationResult on the final result object
        acquireTokenSilentResult.setLocalAuthenticationResult(authenticationResult);
    } else {
        if (tokenResult.getErrorResponse() != null) {
            final String errorCode = tokenResult.getErrorResponse().getError();
            final String subErrorCode = tokenResult.getErrorResponse().getSubError();
            Logger.info(TAG, "Error: " + errorCode + " Suberror: " + subErrorCode);
            if (INVALID_GRANT.equals(errorCode) && BAD_TOKEN.equals(subErrorCode)) {
                boolean isRemoved = tokenCache.removeCredential(cacheRecord.getRefreshToken());
                Logger.info(TAG, "Refresh token is invalid, " + "attempting to delete the RT from cache, result:" + isRemoved);
            }
        } else {
            Logger.warn(TAG, "Invalid state, No token success or error response on the token result");
        }
    }
}
Also used : CliTelemInfo(com.microsoft.identity.common.internal.telemetry.CliTelemInfo) ICacheRecord(com.microsoft.identity.common.internal.cache.ICacheRecord) TokenResult(com.microsoft.identity.common.internal.providers.oauth2.TokenResult) AcquireTokenResult(com.microsoft.identity.common.internal.result.AcquireTokenResult) CacheEndEvent(com.microsoft.identity.common.internal.telemetry.events.CacheEndEvent) RefreshTokenRecord(com.microsoft.identity.common.internal.dto.RefreshTokenRecord) LocalAuthenticationResult(com.microsoft.identity.common.internal.result.LocalAuthenticationResult)

Example 15 with RefreshTokenRecord

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

the class SharedPreferencesAccountCredentialCacheTest method getCredentialsNoClientId.

@Test
public void getCredentialsNoClientId() {
    // Save an AccessToken into the cache
    final AccessTokenRecord accessToken = new AccessTokenRecord();
    accessToken.setCredentialType(CredentialType.AccessToken.name());
    accessToken.setHomeAccountId(HOME_ACCOUNT_ID);
    accessToken.setRealm(REALM);
    accessToken.setEnvironment(ENVIRONMENT);
    accessToken.setClientId(CLIENT_ID);
    accessToken.setTarget(TARGET);
    accessToken.setCachedAt(CACHED_AT);
    accessToken.setExpiresOn(EXPIRES_ON);
    accessToken.setSecret(SECRET);
    mSharedPreferencesAccountCredentialCache.saveCredential(accessToken);
    // Save a RefreshToken into the cache
    final RefreshTokenRecord refreshToken = new RefreshTokenRecord();
    refreshToken.setCredentialType(CredentialType.RefreshToken.name());
    refreshToken.setEnvironment(ENVIRONMENT);
    refreshToken.setHomeAccountId(HOME_ACCOUNT_ID);
    refreshToken.setClientId(CLIENT_ID + "2");
    refreshToken.setSecret(SECRET);
    refreshToken.setTarget(TARGET);
    mSharedPreferencesAccountCredentialCache.saveCredential(refreshToken);
    final List<Credential> credentials = mSharedPreferencesAccountCredentialCache.getCredentialsFilteredBy(HOME_ACCOUNT_ID, ENVIRONMENT, null, null, REALM, TARGET, BEARER_AUTHENTICATION_SCHEME.getName());
    assertEquals(2, credentials.size());
}
Also used : Credential(com.microsoft.identity.common.internal.dto.Credential) 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

RefreshTokenRecord (com.microsoft.identity.common.internal.dto.RefreshTokenRecord)63 PrimaryRefreshTokenRecord (com.microsoft.identity.common.internal.dto.PrimaryRefreshTokenRecord)51 Test (org.junit.Test)51 Credential (com.microsoft.identity.common.internal.dto.Credential)32 AccessTokenRecord (com.microsoft.identity.common.internal.dto.AccessTokenRecord)29 AccountRecord (com.microsoft.identity.common.internal.dto.AccountRecord)10 IdTokenRecord (com.microsoft.identity.common.internal.dto.IdTokenRecord)9 JsonElement (com.google.gson.JsonElement)4 JsonPrimitive (com.google.gson.JsonPrimitive)4 HashMap (java.util.HashMap)4 ICacheRecord (com.microsoft.identity.common.internal.cache.ICacheRecord)3 JSONObject (org.json.JSONObject)3 Nullable (androidx.annotation.Nullable)2 ClientException (com.microsoft.identity.common.exception.ClientException)2 ClientInfo (com.microsoft.identity.common.internal.providers.microsoft.azureactivedirectory.ClientInfo)2 CacheEndEvent (com.microsoft.identity.common.internal.telemetry.events.CacheEndEvent)2 JSONArray (org.json.JSONArray)2 JsonArray (com.google.gson.JsonArray)1 JsonObject (com.google.gson.JsonObject)1 StorageHelper (com.microsoft.identity.common.adal.internal.cache.StorageHelper)1