internal async override Task PreRunAsync() { IAccount account = await GetAccountFromParamsOrLoginHintAsync(_silentParameters).ConfigureAwait(false); AuthenticationRequestParameters.Account = account; AuthenticationRequestParameters.Authority = AuthenticationRequestParameters.AuthorityOverride == null ? Authority.CreateAuthorityWithTenant(ServiceBundle.Config.AuthorityInfo, account?.HomeAccountId?.TenantId) : Authority.CreateAuthorityWithOverride( AuthenticationRequestParameters.AuthorityOverride, ServiceBundle.Config.AuthorityInfo); }
internal static void AuthorityDoesNotUpdateTenant(string authorityUri, string actualTenant) { Authority authority = AuthorityTestHelper.CreateAuthorityFromUrl(authorityUri); Assert.AreEqual(actualTenant, authority.GetTenantId()); string updatedAuthority = authority.GetTenantedAuthority("other_tenant_id"); Assert.AreEqual(actualTenant, authority.GetTenantId()); Assert.AreEqual(updatedAuthority, authorityUri); authority = Authority.CreateAuthorityWithTenant(authority.AuthorityInfo, "other_tenant_id_2"); Assert.AreEqual(authority.AuthorityInfo.CanonicalAuthority, authorityUri); }
public void TenantlessAuthorityChanges() { Authority authority = AuthorityTestHelper.CreateAuthorityFromUrl( TestConstants.AuthorityCommonTenant); Assert.AreEqual("common", authority.TenantId); string updatedAuthority = authority.GetTenantedAuthority(TestConstants.Utid); Assert.AreEqual(TestConstants.AuthorityUtidTenant, updatedAuthority); Assert.AreEqual(updatedAuthority, TestConstants.AuthorityUtidTenant); authority = Authority.CreateAuthorityWithTenant( authority.AuthorityInfo, TestConstants.Utid); Assert.AreEqual(authority.AuthorityInfo.CanonicalAuthority, TestConstants.AuthorityUtidTenant); }
public void GlobalSetup() { var serviceBundle = TestCommon.CreateServiceBundleWithCustomHttpManager(null, isLegacyCacheEnabled: EnableLegacyCache); _requestContext = new RequestContext(serviceBundle, Guid.NewGuid()); _cache = new TokenCache(serviceBundle, false); _response = TestConstants.CreateMsalTokenResponse(); _requestParams = TestCommon.CreateAuthenticationRequestParameters(serviceBundle); _requestParams.TenantUpdatedCanonicalAuthority = Authority.CreateAuthorityWithTenant( _requestParams.AuthorityInfo, TestConstants.Utid); _requestParams.Account = new Account(TestConstants.s_userIdentifier, $"1{TestConstants.DisplayableId}", TestConstants.ProductionPrefNetworkEnvironment); AddHostToInstanceCache(serviceBundle, TestConstants.ProductionPrefCacheEnvironment); LegacyTokenCacheHelper.PopulateLegacyCache(serviceBundle.DefaultLogger, _cache.LegacyPersistence, TokenCacheSize); TokenCacheHelper.AddRefreshTokensToCache(_cache.Accessor, TokenCacheSize); }
protected async Task <AuthenticationResult> CacheTokenResponseAndCreateAuthenticationResultAsync(MsalTokenResponse msalTokenResponse) { // developer passed in user object. AuthenticationRequestParameters.RequestContext.Logger.Info("Checking client info returned from the server.."); ClientInfo fromServer = null; if (!AuthenticationRequestParameters.IsClientCredentialRequest && AuthenticationRequestParameters.ApiId != ApiEvent.ApiIds.AcquireTokenByRefreshToken && AuthenticationRequestParameters.AuthorityInfo.AuthorityType != AuthorityType.Adfs) { //client_info is not returned from client credential flows because there is no user present. fromServer = ClientInfo.CreateFromJson(msalTokenResponse.ClientInfo); } ValidateAccountIdentifiers(fromServer); IdToken idToken = IdToken.Parse(msalTokenResponse.IdToken); AuthenticationRequestParameters.TenantUpdatedCanonicalAuthority = Authority.CreateAuthorityWithTenant(AuthenticationRequestParameters.Authority.AuthorityInfo, idToken?.TenantId); AuthenticationRequestParameters.RequestContext.Logger.Info("Saving Token Response to cache.."); var tuple = await CacheManager.SaveTokenResponseAsync(msalTokenResponse).ConfigureAwait(false); var atItem = tuple.Item1; var idtItem = tuple.Item2; return(new AuthenticationResult( atItem, idtItem, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, msalTokenResponse.TokenSource)); }
public async Task SaveMultipleAppmetadataAsync() { var serviceBundle = TestCommon.CreateDefaultServiceBundle(); ITokenCacheInternal cache = new TokenCache(serviceBundle); MsalTokenResponse response = TestConstants.CreateMsalTokenResponse(); MsalTokenResponse response2 = TestConstants.CreateMsalTokenResponse(); response2.FamilyId = "1"; var requestParams = CreateAuthenticationRequestParameters(serviceBundle); requestParams.TenantUpdatedCanonicalAuthority = Authority.CreateAuthorityWithTenant( requestParams.AuthorityInfo, TestConstants.Utid); AddHostToInstanceCache(serviceBundle, TestConstants.ProductionPrefNetworkEnvironment); await cache.SaveTokenResponseAsync(requestParams, response).ConfigureAwait(false); await cache.SaveTokenResponseAsync(requestParams, response2).ConfigureAwait(false); cache.Accessor.AssertItemCount( expectedAtCount: 1, expectedRtCount: 2, // a normal RT and an FRT expectedAccountCount: 1, expectedIdtCount: 1, expectedAppMetadataCount: 1); var metadata = cache.Accessor.GetAllAppMetadata().First(); Assert.AreEqual(TestConstants.ClientId, metadata.ClientId); Assert.AreEqual(TestConstants.ProductionPrefNetworkEnvironment, metadata.Environment); Assert.AreEqual(TestConstants.FamilyId, metadata.FamilyId); Assert.IsTrue(cache.Accessor.GetAllRefreshTokens().Any(rt => rt.FamilyId == "1")); Assert.IsTrue(cache.Accessor.GetAllRefreshTokens().Any(rt => string.IsNullOrEmpty(rt.FamilyId))); }
async Task <Tuple <MsalAccessTokenCacheItem, MsalIdTokenCacheItem, Account> > ITokenCacheInternal.SaveTokenResponseAsync( AuthenticationRequestParameters requestParams, MsalTokenResponse response) { response.Log(requestParams.RequestContext.Logger, LogLevel.Verbose); MsalAccessTokenCacheItem msalAccessTokenCacheItem = null; MsalRefreshTokenCacheItem msalRefreshTokenCacheItem = null; MsalIdTokenCacheItem msalIdTokenCacheItem = null; MsalAccountCacheItem msalAccountCacheItem = null; IdToken idToken = IdToken.Parse(response.IdToken); if (idToken == null) { requestParams.RequestContext.Logger.Info("ID Token not present in response. "); } var tenantId = GetTenantId(idToken, requestParams); bool isAdfsAuthority = requestParams.AuthorityInfo.AuthorityType == AuthorityType.Adfs; string preferredUsername = GetPreferredUsernameFromIdToken(isAdfsAuthority, idToken); string username = isAdfsAuthority ? idToken?.Upn : preferredUsername; string homeAccountId = GetHomeAccountId(requestParams, response, idToken); string suggestedWebCacheKey = SuggestedWebCacheKeyFactory.GetKeyFromResponse(requestParams, homeAccountId); // Do a full instance discovery when saving tokens (if not cached), // so that the PreferredNetwork environment is up to date. var instanceDiscoveryMetadata = await ServiceBundle.InstanceDiscoveryManager .GetMetadataEntryAsync( requestParams.Authority.AuthorityInfo, requestParams.RequestContext) .ConfigureAwait(false); #region Create Cache Objects if (!string.IsNullOrEmpty(response.AccessToken)) { msalAccessTokenCacheItem = new MsalAccessTokenCacheItem( instanceDiscoveryMetadata.PreferredCache, requestParams.AppConfig.ClientId, response, tenantId, homeAccountId, requestParams.AuthenticationScheme.KeyId) { UserAssertionHash = requestParams.UserAssertion?.AssertionHash, IsAdfs = isAdfsAuthority }; } if (!string.IsNullOrEmpty(response.RefreshToken)) { msalRefreshTokenCacheItem = new MsalRefreshTokenCacheItem( instanceDiscoveryMetadata.PreferredCache, requestParams.AppConfig.ClientId, response, homeAccountId); if (!_featureFlags.IsFociEnabled) { msalRefreshTokenCacheItem.FamilyId = null; } } Dictionary <string, string> wamAccountIds = GetWamAccountIds(requestParams, response); Account account; if (idToken != null) { msalIdTokenCacheItem = new MsalIdTokenCacheItem( instanceDiscoveryMetadata.PreferredCache, requestParams.AppConfig.ClientId, response, tenantId, homeAccountId) { IsAdfs = isAdfsAuthority }; msalAccountCacheItem = new MsalAccountCacheItem( instanceDiscoveryMetadata.PreferredCache, response.ClientInfo, homeAccountId, idToken, preferredUsername, tenantId, wamAccountIds); } #endregion account = new Account( homeAccountId, username, instanceDiscoveryMetadata.PreferredNetwork, wamAccountIds); requestParams.RequestContext.Logger.Verbose("[SaveTokenResponseAsync] Entering token cache semaphore. "); await _semaphoreSlim.WaitAsync().ConfigureAwait(false); requestParams.RequestContext.Logger.Verbose("[SaveTokenResponseAsync] Entered token cache semaphore. "); try { #pragma warning disable CS0618 // Type or member is obsolete HasStateChanged = true; #pragma warning restore CS0618 // Type or member is obsolete try { ITokenCacheInternal tokenCacheInternal = this; if (tokenCacheInternal.IsTokenCacheSerialized()) { var args = new TokenCacheNotificationArgs( this, ClientId, account, hasStateChanged: true, tokenCacheInternal.IsApplicationCache, hasTokens: tokenCacheInternal.HasTokensNoLocks(), requestParams.RequestContext.UserCancellationToken, suggestedCacheKey: suggestedWebCacheKey); Stopwatch sw = Stopwatch.StartNew(); await tokenCacheInternal.OnBeforeAccessAsync(args).ConfigureAwait(false); await tokenCacheInternal.OnBeforeWriteAsync(args).ConfigureAwait(false); requestParams.RequestContext.ApiEvent.DurationInCacheInMs += sw.ElapsedMilliseconds; } if (msalAccessTokenCacheItem != null) { requestParams.RequestContext.Logger.Info("Saving AT in cache and removing overlapping ATs..."); DeleteAccessTokensWithIntersectingScopes( requestParams, instanceDiscoveryMetadata.Aliases, tenantId, msalAccessTokenCacheItem.ScopeSet, msalAccessTokenCacheItem.HomeAccountId, msalAccessTokenCacheItem.TokenType); _accessor.SaveAccessToken(msalAccessTokenCacheItem); } if (idToken != null) { requestParams.RequestContext.Logger.Info("Saving Id Token and Account in cache ..."); _accessor.SaveIdToken(msalIdTokenCacheItem); MergeWamAccountIds(msalAccountCacheItem); _accessor.SaveAccount(msalAccountCacheItem); } // if server returns the refresh token back, save it in the cache. if (msalRefreshTokenCacheItem != null) { requestParams.RequestContext.Logger.Info("Saving RT in cache..."); _accessor.SaveRefreshToken(msalRefreshTokenCacheItem); } UpdateAppMetadata(requestParams.AppConfig.ClientId, instanceDiscoveryMetadata.PreferredCache, response.FamilyId); // Do not save RT in ADAL cache for client credentials flow or B2C if (ServiceBundle.Config.LegacyCacheCompatibilityEnabled && !requestParams.IsClientCredentialRequest && requestParams.AuthorityInfo.AuthorityType != AuthorityType.B2C) { var tenatedAuthority = Authority.CreateAuthorityWithTenant(requestParams.AuthorityInfo, tenantId); var authorityWithPreferredCache = Authority.CreateAuthorityWithEnvironment( tenatedAuthority.AuthorityInfo, instanceDiscoveryMetadata.PreferredCache); CacheFallbackOperations.WriteAdalRefreshToken( Logger, LegacyCachePersistence, msalRefreshTokenCacheItem, msalIdTokenCacheItem, authorityWithPreferredCache.AuthorityInfo.CanonicalAuthority, msalIdTokenCacheItem.IdToken.ObjectId, response.Scope); } } finally { ITokenCacheInternal tokenCacheInternal = this; if (tokenCacheInternal.IsTokenCacheSerialized()) { var args = new TokenCacheNotificationArgs( this, ClientId, account, hasStateChanged: true, tokenCacheInternal.IsApplicationCache, tokenCacheInternal.HasTokensNoLocks(), requestParams.RequestContext.UserCancellationToken, suggestedCacheKey: suggestedWebCacheKey); Stopwatch sw = Stopwatch.StartNew(); await tokenCacheInternal.OnAfterAccessAsync(args).ConfigureAwait(false); requestParams.RequestContext.ApiEvent.DurationInCacheInMs += sw.ElapsedMilliseconds; } #pragma warning disable CS0618 // Type or member is obsolete HasStateChanged = false; #pragma warning restore CS0618 // Type or member is obsolete } return(Tuple.Create(msalAccessTokenCacheItem, msalIdTokenCacheItem, account)); } finally { _semaphoreSlim.Release(); requestParams.RequestContext.Logger.Verbose("[SaveTokenResponseAsync] Released token cache semaphore. "); } }