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. ");
            }
        }
Пример #2
0
        private static string GetHomeAccountId(AdalResultWrapper adalResultWrapper)
        {
            if (!string.IsNullOrEmpty(adalResultWrapper.RawClientInfo))
            {
                return(ClientInfo.CreateFromJson(adalResultWrapper.RawClientInfo).ToAccountIdentifier());
            }

            return(null);
        }
Пример #3
0
        public static IDictionary <AdalTokenCacheKey, AdalResultWrapper> Deserialize(ICoreLogger logger, byte[] state)
        {
            IDictionary <AdalTokenCacheKey, AdalResultWrapper> dictionary =
                new Dictionary <AdalTokenCacheKey, AdalResultWrapper>();

            if (state == null || state.Length == 0)
            {
                return(dictionary);
            }

            using (Stream stream = new MemoryStream())
            {
                BinaryWriter writer = new BinaryWriter(stream);
                writer.Write(state);
                writer.Flush();
                stream.Position = 0;

                BinaryReader reader            = new BinaryReader(stream);
                int          blobSchemaVersion = reader.ReadInt32();
                if (blobSchemaVersion != SchemaVersion)
                {
                    logger.Warning("The version of the persistent state of the cache does not match the current schema, so skipping deserialization.");
                    return(dictionary);
                }

                int count = reader.ReadInt32();
                for (int n = 0; n < count; n++)
                {
                    string keyString = reader.ReadString();

                    string[]          kvpElements = keyString.Split(new[] { Delimiter }, StringSplitOptions.None);
                    AdalResultWrapper resultEx    = AdalResultWrapper.Deserialize(reader.ReadString());
                    AdalTokenCacheKey key         = new AdalTokenCacheKey(kvpElements[0], kvpElements[1], kvpElements[2],
                                                                          (TokenSubjectType)int.Parse(kvpElements[3], CultureInfo.CurrentCulture),
                                                                          resultEx.Result.UserInfo);

                    dictionary.Add(key, resultEx);
                }

                logger.Info(string.Format(CultureInfo.CurrentCulture, "Deserialized {0} items to token cache.", count));
            }

            return(dictionary);
        }
        public static void WriteMsalRefreshToken(ITokenCacheAccessor tokenCacheAccessor,
                                                 AdalResultWrapper resultWrapper, string authority, string clientId, string displayableId,
                                                 string givenName, string familyName, string objectId)
        {
            if (string.IsNullOrEmpty(resultWrapper.RawClientInfo))
            {
                MsalLogger.Default.Info("Client Info is missing. Skipping MSAL refresh token cache write");
                return;
            }

            if (string.IsNullOrEmpty(resultWrapper.RefreshToken))
            {
                MsalLogger.Default.Info("Refresh Token is missing. Skipping MSAL refresh token cache write");
                return;
            }

            if (string.IsNullOrEmpty(resultWrapper.Result.IdToken))
            {
                MsalLogger.Default.Info("Id Token is missing. Skipping MSAL refresh token cache write");
                return;
            }

            try
            {
                var rtItem = new MsalRefreshTokenCacheItem
                                 (new Uri(authority).Host, clientId, resultWrapper.RefreshToken, resultWrapper.RawClientInfo);
                tokenCacheAccessor.SaveRefreshToken(rtItem);

                MsalAccountCacheItem accountCacheItem = new MsalAccountCacheItem
                                                            (new Uri(authority).Host, objectId, resultWrapper.RawClientInfo, null, displayableId, resultWrapper.Result.TenantId,
                                                            givenName, familyName);
                tokenCacheAccessor.SaveAccount(accountCacheItem);
            }
            catch (Exception ex)
            {
                MsalLogger.Default.WarningPiiWithPrefix(
                    ex,
                    "An error occurred while writing ADAL refresh token to the cache in MSAL format. "
                    + "For details please see https://aka.ms/net-cache-persistence-errors. ");
            }
        }