Пример #1
0
        internal void StoreToCache(AuthenticationResultEx result, string authority, string resource, string clientId, TokenSubjectType subjectType, CallState callState)
        {
            lock (cacheLock)
            {
                PlatformPlugin.Logger.Verbose(callState, "Storing token in the cache...");

                string uniqueId      = (result.Result.UserInfo != null) ? result.Result.UserInfo.UniqueId : null;
                string displayableId = (result.Result.UserInfo != null) ? result.Result.UserInfo.DisplayableId : null;

                this.OnBeforeWrite(new TokenCacheNotificationArgs
                {
                    Resource      = resource,
                    ClientId      = clientId,
                    UniqueId      = uniqueId,
                    DisplayableId = displayableId
                });

                TokenCacheKey tokenCacheKey = new TokenCacheKey(authority, resource, clientId, subjectType,
                                                                result.Result.UserInfo);
                this.tokenCacheDictionary[tokenCacheKey] = result;
                PlatformPlugin.Logger.Verbose(callState, "An item was stored in the cache");
                this.UpdateCachedMrrtRefreshTokens(result, clientId, subjectType);

                this.HasStateChanged = true;
            }
        }
Пример #2
0
 /// <summary>
 /// Determines whether the specified TokenCacheKey is equal to the current object.
 /// </summary>
 /// <returns>
 /// true if the specified TokenCacheKey is equal to the current object; otherwise, false.
 /// </returns>
 /// <param name="other">The TokenCacheKey to compare with the current object. </param><filterpriority>2</filterpriority>
 public bool Equals(TokenCacheKey other)
 {
     return(ReferenceEquals(this, other) ||
            (other != null &&
             (other.Authority == this.Authority) &&
             this.ResourceEquals(other.Resource) &&
             this.ClientIdEquals(other.ClientId) &&
             (other.UniqueId == this.UniqueId) &&
             this.DisplayableIdEquals(other.DisplayableId) &&
             (other.TokenSubjectType == this.TokenSubjectType)));
 }
Пример #3
0
        /// <summary>
        /// Deserializes state of the cache. The state should be the blob received earlier by calling the method Serialize.
        /// </summary>
        /// <param name="state">State of the cache as a blob</param>
        public void Deserialize(byte[] state)
        {
            lock (cacheLock)
            {
                if (state == null)
                {
                    this.tokenCacheDictionary.Clear();
                    return;
                }

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

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

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

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

                        this.tokenCacheDictionary.Add(key, resultEx);
                    }

                    PlatformPlugin.Logger.Information(null,
                                                      string.Format(CultureInfo.CurrentCulture, "Deserialized {0} items to token cache.", count));
                }
            }
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        internal TokenCacheItem(TokenCacheKey key, AuthenticationResult result)
        {
            this.Authority        = key.Authority;
            this.Resource         = key.Resource;
            this.ClientId         = key.ClientId;
            this.TokenSubjectType = key.TokenSubjectType;
            this.UniqueId         = key.UniqueId;
            this.DisplayableId    = key.DisplayableId;
            this.TenantId         = result.TenantId;
            this.ExpiresOn        = result.ExpiresOn;
            this.AccessToken      = result.AccessToken;
            this.IdToken          = result.IdToken;

            if (result.UserInfo != null)
            {
                this.FamilyName       = result.UserInfo.FamilyName;
                this.GivenName        = result.UserInfo.GivenName;
                this.IdentityProvider = result.UserInfo.IdentityProvider;
            }
        }
Пример #5
0
        /// <summary>
        /// Deletes an item from the cache.
        /// </summary>
        /// <param name="item">The item to delete from the cache</param>
        public virtual void DeleteItem(TokenCacheItem item)
        {
            lock (cacheLock)
            {
                if (item == null)
                {
                    throw new ArgumentNullException("item");
                }

                TokenCacheNotificationArgs args = new TokenCacheNotificationArgs
                {
                    TokenCache    = this,
                    Resource      = item.Resource,
                    ClientId      = item.ClientId,
                    UniqueId      = item.UniqueId,
                    DisplayableId = item.DisplayableId
                };

                this.OnBeforeAccess(args);
                this.OnBeforeWrite(args);

                TokenCacheKey toRemoveKey = this.tokenCacheDictionary.Keys.FirstOrDefault(item.Match);
                if (toRemoveKey != null)
                {
                    this.tokenCacheDictionary.Remove(toRemoveKey);
                    PlatformPlugin.Logger.Information(null, "One item removed successfully");
                }
                else
                {
                    PlatformPlugin.Logger.Information(null, "Item not Present in the Cache");
                }

                this.HasStateChanged = true;
                this.OnAfterAccess(args);
            }
        }
Пример #6
0
        /// <summary>
        /// Determines whether the specified object is equal to the current object.
        /// </summary>
        /// <returns>
        /// true if the specified object is equal to the current object; otherwise, false.
        /// </returns>
        /// <param name="obj">The object to compare with the current object. </param><filterpriority>2</filterpriority>
        public override bool Equals(object obj)
        {
            TokenCacheKey other = obj as TokenCacheKey;

            return((other != null) && this.Equals(other));
        }
 internal bool Match(TokenCacheKey key)
 {
     return(key.Authority == this.Authority && key.ResourceEquals(this.Resource) && key.ClientIdEquals(this.ClientId) &&
            key.TokenSubjectType == this.TokenSubjectType && key.UniqueId == this.UniqueId && key.DisplayableIdEquals(this.DisplayableId));
 }
Пример #8
0
        internal AuthenticationResultEx LoadFromCache(CacheQueryData cacheQueryData, CallState callState)
        {
            lock (cacheLock)
            {
                PlatformPlugin.Logger.Verbose(callState, "Looking up cache for a token...");

                AuthenticationResultEx resultEx = null;

                KeyValuePair <TokenCacheKey, AuthenticationResultEx>?kvp = this.LoadSingleItemFromCache(cacheQueryData, callState);

                if (kvp.HasValue)
                {
                    TokenCacheKey cacheKey = kvp.Value.Key;
                    resultEx = kvp.Value.Value;
                    bool tokenNearExpiry = (resultEx.Result.ExpiresOn <=
                                            DateTime.UtcNow + TimeSpan.FromMinutes(ExpirationMarginInMinutes));

                    if (tokenNearExpiry)
                    {
                        resultEx.Result.AccessToken = null;
                        PlatformPlugin.Logger.Verbose(callState,
                                                      "An expired or near expiry token was found in the cache");
                    }
                    else if (!cacheKey.ResourceEquals(cacheQueryData.Resource))
                    {
                        PlatformPlugin.Logger.Verbose(callState,
                                                      string.Format(CultureInfo.CurrentCulture,
                                                                    "Multi resource refresh token for resource '{0}' will be used to acquire token for '{1}'",
                                                                    cacheKey.Resource, cacheQueryData.Resource));
                        var newResultEx = new AuthenticationResultEx
                        {
                            Result             = new AuthenticationResult(null, null, DateTimeOffset.MinValue),
                            RefreshToken       = resultEx.RefreshToken,
                            ResourceInResponse = resultEx.ResourceInResponse
                        };

                        newResultEx.Result.UpdateTenantAndUserInfo(resultEx.Result.TenantId, resultEx.Result.IdToken,
                                                                   resultEx.Result.UserInfo);
                        resultEx = newResultEx;
                    }
                    else
                    {
                        PlatformPlugin.Logger.Verbose(callState,
                                                      string.Format(CultureInfo.CurrentCulture, "{0} minutes left until token in cache expires",
                                                                    (resultEx.Result.ExpiresOn - DateTime.UtcNow).TotalMinutes));
                    }

                    if (resultEx.Result.AccessToken == null && resultEx.RefreshToken == null)
                    {
                        this.tokenCacheDictionary.Remove(cacheKey);
                        PlatformPlugin.Logger.Information(callState, "An old item was removed from the cache");
                        this.HasStateChanged = true;
                        resultEx             = null;
                    }

                    if (resultEx != null)
                    {
                        PlatformPlugin.Logger.Information(callState,
                                                          "A matching item (access token or refresh token or both) was found in the cache");
                    }
                }
                else
                {
                    PlatformPlugin.Logger.Information(callState, "No matching token was found in the cache");
                }

                return(resultEx);
            }
        }