/// <summary> /// Algorithm to delete: /// /// DisplayableId cannot be null /// Removal is scoped by enviroment and clientId; /// /// If accountId != null then delete everything with the same clientInfo /// otherwise, delete everything with the same displayableId /// /// Notes: /// - displayableId can change rarely /// - ClientCredential Grant uses the app token cache, not the user token cache, so this algorithm does not apply /// (nor will GetAccounts / RemoveAccount work) /// /// </summary> public static void RemoveAdalUser( ILegacyCachePersistence legacyCachePersistence, string clientId, string displayableId, string accountOrUserId) { try { IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCache = AdalCacheOperations.Deserialize(legacyCachePersistence.LoadCache()); if (!string.IsNullOrEmpty(accountOrUserId)) { RemoveEntriesWithMatchingId(clientId, accountOrUserId, adalCache); } RemoveEntriesWithMatchingName(clientId, displayableId, adalCache); legacyCachePersistence.WriteCache(AdalCacheOperations.Serialize(adalCache)); } catch (Exception ex) { MsalLogger.Default.WarningPiiWithPrefix(ex, "An error occurred while deleting account in ADAL format from the cache. " + "For details please see https://aka.ms/net-cache-persistence-errors. "); } }
public static MsalRefreshTokenCacheItem GetAdalEntryForMsal( ICoreLogger logger, ILegacyCachePersistence legacyCachePersistence, IEnumerable <string> environmentAliases, string clientId, string upn, string uniqueId) { IEnumerable <MsalRefreshTokenCacheItem> adalRts = GetAllAdalEntriesForMsal( logger, legacyCachePersistence, environmentAliases, clientId, upn, uniqueId); IEnumerable <IGrouping <string, MsalRefreshTokenCacheItem> > rtGroupsByEnv = adalRts.GroupBy(rt => rt.Environment.ToLowerInvariant()); // if we have more than 1 RT per env, there is smth wrong with the ADAL cache if (rtGroupsByEnv.Any(g => g.Count() > 1)) { //Due to the fact that there is a problem with the ADAL cache that causes this exception, The ADAL cache will be removed when //this exception is triggered so that users can sign in interactivly and repopulate the cache. IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCache = AdalCacheOperations.Deserialize(logger, legacyCachePersistence.LoadCache()); adalCache.Clear(); logger.Error(MsalErrorMessage.InvalidAdalCacheMultipleRTs); legacyCachePersistence.WriteCache(AdalCacheOperations.Serialize(logger, adalCache)); return(null); } return(adalRts.FirstOrDefault()); }
public static void WriteAdalRefreshToken( ILegacyCachePersistence legacyCachePersistence, MsalRefreshTokenCacheItem rtItem, MsalIdTokenCacheItem idItem, string authority, string uniqueId, string scope) { try { if (rtItem == null) { MsalLogger.Default.Info("No refresh token available. Skipping MSAL refresh token cache write"); return; } //Using scope instead of resource because that value does not exist. STS should return it. AdalTokenCacheKey key = new AdalTokenCacheKey(authority, scope, rtItem.ClientId, TokenSubjectType.User, uniqueId, idItem.IdToken.PreferredUsername); AdalResultWrapper wrapper = new AdalResultWrapper() { Result = new AdalResult(null, null, DateTimeOffset.MinValue) { UserInfo = new AdalUserInfo() { UniqueId = uniqueId, DisplayableId = idItem.IdToken.PreferredUsername } }, RefreshToken = rtItem.Secret, RawClientInfo = rtItem.RawClientInfo, //ResourceInResponse is needed to treat RT as an MRRT. See IsMultipleResourceRefreshToken //property in AdalResultWrapper and its usage. Stronger design would be for the STS to return resource //for which the token was issued as well on v2 endpoint. ResourceInResponse = scope }; IDictionary <AdalTokenCacheKey, AdalResultWrapper> dictionary = AdalCacheOperations.Deserialize(legacyCachePersistence.LoadCache()); dictionary[key] = wrapper; legacyCachePersistence.WriteCache(AdalCacheOperations.Serialize(dictionary)); } catch (Exception ex) { if (!string.Equals(rtItem?.Environment, idItem?.Environment, StringComparison.OrdinalIgnoreCase)) { MsalLogger.Default.Error(DifferentEnvError); } if (!string.Equals(rtItem?.Environment, new Uri(authority).Host, StringComparison.OrdinalIgnoreCase)) { MsalLogger.Default.Error(DifferentAuthorityError); } MsalLogger.Default.WarningPiiWithPrefix(ex, "An error occurred while writing MSAL refresh token to the cache in ADAL format. " + "For details please see https://aka.ms/net-cache-persistence-errors. "); } }