/// <summary>
        /// Initializes a new instance of the <see cref="CustomThrottlingHandler"/> class.
        /// </summary>
        /// <param name="log">Log</param>
        /// <param name="syncSettingsReader">synchronous settings reader</param>
        public CustomThrottlingHandler(ILog log, ISettingsReader syncSettingsReader)
            : base()
        {
            this.log   = log;
            this.alert = (string msg, Exception ex) => this.log.LogError(msg, ex);

            // Read the rate limit from the configuration
            long rateLimitPerMinute = Convert.ToInt64(syncSettingsReader.ReadValue("RateLimitPerMinute"));

            // The policy reads the threshold from the settings reader
            ThrottlePolicy throttlePolicyOnStartup = new ThrottlePolicy(perMinute: rateLimitPerMinute)
            {
                ClientThrottling = true
            };

            // Bug fixes <-- WebApiThrottle has a bug. Setting these to null tells WebApiThrottle that we do not do ip-based nor endpoint-based
            // rate limiting. We avoid the bug this way.
            throttlePolicyOnStartup.IpRules       = null;
            throttlePolicyOnStartup.EndpointRules = null;

            // Assign the static throttle policy on startup. Throttle on clients (meaning app keys).
            this.Policy = throttlePolicyOnStartup;

            this.Repository       = new CacheRepository();
            this.Logger           = new TracingThrottleLogger(this.log);
            this.PolicyRepository = new PolicyCacheRepository();

            // Set the throttle policy to update every 24 hours
            this.srvThrottlePolicy = new SelfRefreshingVar <IPolicyRepository>(this.PolicyRepository, TimeUtils.TwentyFourHours, this.RefreshingThottlePolicy, this.alert);
        }
Beispiel #2
0
        public void IncrementSRVTest()
        {
            this.counter = 0;
            SelfRefreshingVar <int> srv = new SelfRefreshingVar <int>(0, TimeSpan.FromSeconds(3), this.AtomicIncrement, this.failTest);

            // sleep for 10 seconds, and check if value is 3
            Thread.Sleep(10 * 1000);
            Assert.AreEqual(3, srv.GetValue());
        }
Beispiel #3
0
        public async Task UnInitSRVTest()
        {
            this.counter = 0;
            SelfRefreshingVar <int> srv = new SelfRefreshingVar <int>(TimeSpan.FromSeconds(10), this.AtomicIncrement, this.failTest);

            Assert.AreEqual(0, srv.GetValue());
            await srv.Initialize();

            Assert.AreEqual(1, srv.GetValue());
        }
Beispiel #4
0
        public void DisposeSRVTest()
        {
            this.counter = 0;
            SelfRefreshingVar <int> srv = new SelfRefreshingVar <int>(0, TimeSpan.FromSeconds(2), this.AtomicIncrement, this.failTest);

            // sleep for 3 seconds
            Thread.Sleep(3 * 1000);

            // Dispose
            srv.Dispose();

            // sleep for another 2 seconds
            Thread.Sleep(2 * 1000);
            Assert.AreEqual(1, srv.GetValue());
        }
        /// <summary>
        /// Validates a token against every single app identity registered with us
        /// </summary>
        /// <param name="token">token</param>
        /// <param name="appHandle">app handle</param>
        /// <returns>list of claims found in the token</returns>
        private async Task <ClaimsPrincipal> ValidateToken(string token, string appHandle)
        {
            token.IfNullOrEmptyThrowEx("AADAuthManager:ValidateToken: token is null");
            appHandle.IfNullOrEmptyThrowEx("AADAuthManager:ValidateToken: appHandle is null");

            // Lookup the validation parameters corresponding to this app handle in our dictionary of srv
            SelfRefreshingVar <TokenValidationParameters> appTokenValidationParameter = null;

            this.srvValidationParameters.TryGetValue(appHandle, out appTokenValidationParameter);

            // If can't find validation parameters, create new ones.
            if (appTokenValidationParameter == null)
            {
                // Construct new token validation parameters
                var appIdentity = await this.ReadIdentityProviderCredentials(appHandle, IdentityProviderType.AADS2S);

                if (appIdentity == null)
                {
                    string errorMessage = $"AADAuthManager:ValidateToken: AAD credentials are missing. appHandle: {appHandle}";
                    this.Log.LogException(errorMessage);
                }

                // Create an initialized self-refreshing variable for the token validation parameters. Refresh the variable every 24 hours.
                var validationParameters = await this.ConstructTokenValidationParameters(appIdentity.ClientId, appIdentity.ClientRedirectUri);

                appTokenValidationParameter = new SelfRefreshingVar <TokenValidationParameters>(validationParameters, TimeUtils.TwentyFourHours, () => this.ConstructTokenValidationParameters(appIdentity.ClientId, appIdentity.ClientRedirectUri), this.alert);

                // Insert the new validation parameters in the dictionary. In case they are already there (due to a race condition), it's ok, we'll overwrite the old ones.
                if (this.srvValidationParameters.TryAdd(appHandle, appTokenValidationParameter) == false)
                {
                    // The self-refreshing variable has been added to the concurrent dictionary by somebody else. Dispose ours
                    appTokenValidationParameter.Dispose();

                    // If we just disposed ours, read the ones from dictionary
                    this.srvValidationParameters.TryGetValue(appHandle, out appTokenValidationParameter);

                    // Sanity check: the read must be successful. We must have non-null validation parameters by now
                    appTokenValidationParameter = appTokenValidationParameter ?? throw new InvalidOperationException("Code should never reach this point.");
                }
            }

            return(this.tokenHandler.ValidateToken(token, appTokenValidationParameter.GetValue(), out this.validatedToken));
        }