/// <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); }
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()); }
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()); }
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)); }